Compare commits

...

42 Commits

Author SHA1 Message Date
bietiaop
b42b6c3cf0 docs(README): update multi-language README.md
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
2026-02-28 12:32:48 +08:00
手瓜一十雪
740d2118f1 Comment out plugin import UI and handlers
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Temporarily disable the local plugin import flow: remove the unused useRef import, comment out the FiUpload import, fileInputRef declaration, and the related handlers (handleImportClick and handleFileChange). Keeps the rest of the plugin page (loading, modal and plugin list logic) intact so the import feature can be re-enabled later.
2026-02-22 13:34:03 +08:00
手瓜一十雪
77bdcfd249 Disable local plugin import and upload handling
Commented out ImportLocalPluginHandler import and the multer upload configuration (50MB limit and .zip file filter). Temporarily disables local plugin .zip uploads, likely for debugging or while refactoring the upload/import flow; can be re-enabled when upload handling is restored.
2026-02-22 13:33:06 +08:00
手瓜一十雪
896e1c209a Disable plugin upload feature
Comment out the backend import route and corresponding frontend upload UI to disable plugin uploads. Backend: commented out POST /Import route in packages/napcat-webui-backend/src/router/Plugin.ts. Frontend: removed (commented) the upload Button and hidden file input in packages/napcat-webui-frontend/src/pages/dashboard/plugin.tsx. This temporarily prevents users from uploading plugins.
2026-02-22 13:15:42 +08:00
手瓜一十雪
cff07c7ce5 Revise README for new maintainer notice
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Updated the README to replace the 'New Feature' section with a 'Notice' about seeking new maintainers and removed outdated information.

Signed-off-by: 手瓜一十雪 <nanaeonn@outlook.com>
2026-02-21 19:22:07 +08:00
手瓜一十雪
5c04b799a6 feat: 提高超时检测等待 2026-02-21 16:21:31 +08:00
ud2
1fc4655ae1 refactor(onebot): 精简 WebSocket 适配器实现 (#1644)
* refactor(onebot): 移除 `async-mutex` 依赖

* fix(onebot): 避免重复发送 WebSocket pong
2026-02-21 15:59:12 +08:00
Eric-Terminal
eb07cdb715 feat: 自动登录失败后回退密码登录并补充独立配置 (#1638)
* feat: 自动登录失败后回退密码登录并补充独立配置

改动文件:
- packages/napcat-webui-backend/src/helper/config.ts
- packages/napcat-webui-backend/src/utils/auto_login.ts
- packages/napcat-webui-backend/src/utils/auto_login_config.ts
- packages/napcat-webui-backend/index.ts
- packages/napcat-webui-backend/src/api/QQLogin.ts
- packages/napcat-webui-backend/src/router/QQLogin.ts
- packages/napcat-webui-frontend/src/controllers/qq_manager.ts
- packages/napcat-webui-frontend/src/pages/dashboard/config/login.tsx
- packages/napcat-test/autoPasswordFallback.test.ts

目的:
- 在启动阶段将自动登录流程从“仅快速登录”扩展为“快速登录失败后自动回退密码登录”,并保持二维码兜底。
- 在 WebUI 登录配置页新增独立的自动回退账号/密码配置,密码仅提交与存储 MD5,不回显明文。

效果:
- 后端配置新增 autoPasswordLoginAccount 与 autoPasswordLoginPasswordMd5 字段,并提供读取、更新(空密码不覆盖)和清空能力。
- 新增 QQLogin API:GetAutoPasswordLoginConfig / SetAutoPasswordLoginConfig / ClearAutoPasswordLoginConfig。
- WebUI 登录配置页新增自动回退密码登录区块,支持保存、刷新、清空及“留空不修改密码”交互。
- 新增自动登录回退逻辑单测与配置补丁构造单测,覆盖快速成功、回退成功、回退失败、无密码兜底等场景。

* feat: 精简为环境变量驱动的快速登录失败密码回退

改动目的:
- 按维护者建议将方案收敛为后端环境变量驱动,不新增 WebUI 配置与路由
- 保留“快速登录失败 -> 密码回退 -> 二维码兜底”核心能力
- 兼容快速启动参数场景,降低评审复杂度

主要改动文件:
- packages/napcat-webui-backend/index.ts
- packages/napcat-shell/base.ts
- packages/napcat-webui-backend/src/api/QQLogin.ts
- packages/napcat-webui-backend/src/helper/config.ts
- packages/napcat-webui-backend/src/router/QQLogin.ts
- packages/napcat-webui-frontend/src/controllers/qq_manager.ts
- packages/napcat-webui-frontend/src/pages/dashboard/config/login.tsx
- 删除:packages/napcat-webui-backend/src/utils/auto_login.ts
- 删除:packages/napcat-webui-backend/src/utils/auto_login_config.ts
- 删除:packages/napcat-test/autoPasswordFallback.test.ts

实现细节:
1. WebUI 启动自动登录链路
- 保留 NAPCAT_QUICK_ACCOUNT 优先逻辑
- 快速登录失败后触发密码回退
- 回退密码来源优先级:
  a) NAPCAT_QUICK_PASSWORD_MD5(32 位 MD5)
  b) NAPCAT_QUICK_PASSWORD(运行时自动计算 MD5)
- 未配置回退密码时保持二维码兜底,并输出带 QQ 号的引导日志

2. Shell 快速登录链路
- quickLoginWithUin 失败判定统一基于 result 码 + errMsg
- 覆盖历史账号不存在、凭证失效、快速登录异常等场景
- 失败后统一进入同一密码回退逻辑,再兜底二维码

3. 文案与可运维性
- 日志明确推荐优先使用 ACCOUNT + NAPCAT_QUICK_PASSWORD
- NAPCAT_QUICK_PASSWORD_MD5 作为备用方式

效果:
- 满足自动回退登录需求,且改动面显著缩小
- 不修改 napcat-docker 仓库代码,直接兼容现有容器启动参数
- 便于上游快速审阅与合并

* fix: 修复 napcat-framework 未使用变量导致的 CI typecheck 失败

改动文件:
- packages/napcat-framework/napcat.ts

问题背景:
- 上游代码中声明了变量 bypassEnabled,但后续未使用
- 在 CI 的全量 TypeScript 检查中触发 TS6133(声明但未读取)
- 导致 PR Build 机器人评论显示构建失败(Type check failed)

具体修复:
- 将以下语句从“赋值后未使用”改为“直接调用”
- 原:const bypassEnabled = napi2nativeLoader.nativeExports.enableAllBypasses?.(bypassOptions);
- 现:napi2nativeLoader.nativeExports.enableAllBypasses?.(bypassOptions);

影响与效果:
- 不改变运行时行为(仍会执行 enableAllBypasses)
- 消除 TS6133 报错,恢复 typecheck 可通过

本地验证:
- pnpm run typecheck:通过
- pnpm run build:framework:通过
- pnpm run build:shell:通过

---------

Co-authored-by: 手瓜一十雪 <nanaeonn@outlook.com>
2026-02-21 14:18:34 +08:00
手瓜一十雪
964fd98914 Add spinner during captcha verification
Show a loading spinner and message while captcha is being verified. Imported Spinner and added an optional captchaVerifying prop to PasswordLogin to toggle between the TencentCaptchaModal and a waiting state. In qq_login.tsx introduced captchaVerifying state, set it true before the captcha login request and reset it in finally, and passed the prop down to the PasswordLogin component.
2026-02-21 13:39:35 +08:00
手瓜一十雪
f9764c9559 Improve new-device QR handling and bypass init
Refactor new-device QR flow and streamline bypass init:

- napcat-shell: stop verbose logging and removed check of enableAllBypasses return value; just invoke native enableAllBypasses when not disabled by env.
- backend (QQLogin): simplify extraction of tokens from jumpUrl (use sig and uin-token), return an error if missing, and send oidbRequest directly (removed nested try/catch and regex fallback).
- frontend (new_device_verify): accept result.str_url without requiring bytes_token and pass an empty string to polling when bytes_token is absent.
- frontend (password_login): change render order to show captcha modal before new-device verification UI.
- frontend (qq_manager): normalize GetNewDeviceQRCode response — derive bytes_token from str_url's str_url query param (base64) when bytes_token is missing, and preserve extra status/error fields in the returned object.

These changes improve robustness when OIDB responses omit bytes_token, reduce noisy logs, and ensure the UI and polling still function.
2026-02-21 13:24:56 +08:00
手瓜一十雪
b71a4913eb Add captcha & new-device QQ login flows
Introduce multi-step QQ password login support (captcha and new-device verification) and related OIDB QR handling.

- Change login signature fields in NodeIKernelLoginService to binary (Uint8Array) and add unusualDeviceCheckSig.
- Update shell base to handle additional result codes (captcha required, new-device, abnormal-device), set login status on success, and register three callbacks: captcha, new-device, and password flows. Use TextEncoder for encoding ticket/randstr/sid and newDevicePullQrCodeSig.
- Extend backend WebUiDataRuntime (types and runtime) with set/request methods for captcha and new-device login calls and adjust LoginRuntime types to return richer metadata (needCaptcha, proofWaterUrl, needNewDevice, jumpUrl, newDevicePullQrCodeSig).
- Add backend API handlers: CaptchaLogin, NewDeviceLogin, GetNewDeviceQRCode and PollNewDeviceQR; add oidbRequest helper using https to query oidb.tim.qq.com for QR generation and polling.
- Wire new handlers into QQLogin router and return structured success responses when further steps are required.
- Add frontend components and pages for captcha and new-device verification (new files: 1.html, new_device_verify.tsx, tencent_captcha.tsx) and update existing frontend controllers/pages to integrate the new flows.
- Improve error logging and user-facing messages for the new flows.

This change enables handling of password-login scenarios requiring captcha or device attestation and provides endpoints to obtain and poll OIDB QR codes for new-device verification.
2026-02-21 13:03:40 +08:00
手瓜一十雪
f961830836 Inline plugin icon helper into PluginCard
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Move getPluginIconUrl from utils/plugin_icon.ts into plugin_card.tsx and remove the now-unused util file. The function behavior is unchanged: it reads webui_token from localStorage and appends it as a query parameter to plugin icon URLs so authenticated icon endpoints can be used as img src.
2026-02-20 23:36:45 +08:00
手瓜一十雪
dd8b5f84a6 Simplify plugin avatar logic
Remove getAuthorAvatar and related homepage/repository parsing. Rely on getPluginIconUrl(icon) (backend-provided URL with token) and fall back to Vercel avatar. Update prop destructuring to drop homepage/repository and streamline avatar selection, removing fragile favicon/GitHub parsing logic.
2026-02-20 23:35:49 +08:00
手瓜一十雪
48ffd5597a Add plugin icon support and caching
Introduce support for plugin icons across backend and frontend. Updates include:

- napcat-onebot: add optional `icon` field to PluginPackageJson.
- Backend (api/Plugin, PluginStore, router): add handlers/utilities to locate and serve plugin icons (`GetPluginIconHandler`, getPluginIconUrl, findPluginIconPath) and wire the route `/api/Plugin/Icon/:pluginId`.
- Cache logic: implement `cachePluginIcon` to fetch GitHub user avatars and store as `data/icon.png` when package.json lacks an icon; invoked after plugin install (regular and SSE flows).
- Frontend: add `icon` to PluginItem, prefer backend-provided icon URL in plugin card (via new getPluginIconUrl util that appends webui_token query param), and add the util to handle token-based image requests.
- Plugin store UI: add a Random category (shuffled), client-side pagination, and reset page on tab/search changes.

These changes let the UI display plugin icons (falling back to author/avatar or Vercel avatars) and cache icons for better UX, while handling auth by passing the token as a query parameter for img src requests.
2026-02-20 23:32:57 +08:00
手瓜一十雪
1b73d68cbf Refactor extension tabs layout and styles
Remove the overflow wrapper around extension tabs and move max-w/full styling to the Tabs component. Simplify classNames (tabList, cursor) and clean up shrinking/truncation classes on tab items and plugin name to improve responsiveness and layout, while preserving the openInNewWindow click behavior.
2026-02-20 23:05:20 +08:00
手瓜一十雪
5fec649425 Load napcat.json, use o3HookMode & bypass
Add loadNapcatConfig helper that reads napcat.json (json5), validates with Ajv and fills defaults for early pre-login use. Change NativePacketHandler.init signature to accept an o3HookMode flag and forward it to native initHook. Update framework and shell to use loadNapcatConfig (remove duplicated file-reading logic) and pass configured o3HookMode and bypass options into Napi2NativeLoader/native packet initialization. Clean up imports (Ajv, path, fs, json5) and remove the old loadBypassConfig helper.
2026-02-20 21:49:19 +08:00
手瓜一十雪
052e7fa2b3 Init nativePacketHandler after loading wrapper && fix #1633
Delay initialization of nativePacketHandler until after loadQQWrapper so that wrapper.node is loaded before initializing hooks. Moved the await nativePacketHandler.init(...) call below loadQQWrapper and added an explanatory comment to ensure native hooks are set up only after the native module is available.
2026-02-20 21:39:50 +08:00
叫我饼干ちゃん
04e425d17a update:汉化 (#1641) 2026-02-20 20:31:36 +08:00
Rinne
cbe0506577 fix(webui): properly center plus icon in add button row (#1642)
Add `flex items-center justify-center` to the plus icon wrapper in `AddButton` so the icon is vertically and horizontally centered. This improves visual alignment and keeps the “新建网络配置” button content consistent.
2026-02-20 20:31:22 +08:00
手瓜一十雪
32ec097f51 Update native binaries for napi2native
Rebuild native artifacts: updated ffmpeg.dll and napi2native Node addons for linux (arm64, x64) and win32 x64. These are binary-only updates (no source changes), likely to refresh builds for compatibility or toolchain/dependency updates.
2026-02-20 19:56:24 +08:00
手瓜一十雪
53f27ea9e2 Refactor Bypass layout and UI text
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Wrap Bypass SwitchCard controls in a responsive grid for better layout and spacing. Rename the Config tab title from 'Bypass配置' to '反检测'. Clean up WebUI button/label text by removing emoji prefixes (removed 📥, 🔐, ) for a cleaner UI. Files changed: bypass.tsx (layout), index.tsx (tab title), webui.tsx (text cleanup).
2026-02-20 17:11:58 +08:00
手瓜一十雪
41d94cd5e2 Refactor bypass defaults and crash handling
Set bypass defaults to disabled and simplify loading: napcat.json default bypass flags changed to false and code now reads bypass options without merging a prior "all enabled" default. Removed the progressive bypass-disable logic and related environment variable usage, and added a log when Napi2NativeLoader enables bypasses. Web UI/backend adjustments: default NapCat config is now generated from the AJV schema; the bypass settings UI defaults to false, adds an o3HookMode toggle, and submits o3HookMode as 0/1. UX fixes: extension tabs made horizontally scrollable with fixed tab sizing, and plugin uninstall flow updated to a single confirmation dialog with an optional checkbox to remove plugin config. Overall changes aim to use safer defaults, simplify crash/restart behavior, and improve configuration and UI clarity.
2026-02-20 16:36:16 +08:00
手瓜一十雪
285d352bc8 Downgrade json5 in napcat-framework
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Update packages/napcat-framework/package.json to use json5@^2.2.3 (was ^3.2.2). This change pins json5 to the v2 line, likely for compatibility with other workspace packages or tooling that require the older major version.
2026-02-18 22:21:55 +08:00
手瓜一十雪
a3b3836b8a Add process bypass option and update bypass fields
Introduce a new 'process' bypass option and remove the old 'maps' key, updating all related schemas, types, defaults and validation. Adjusted napcat.json ordering and NapcatConfig defaults, updated BypassOptions schema and TypeScript interfaces, backend validation keys, loader/default parsing logic, and the web UI form mappings/labels to reflect the new field set and ordering.
2026-02-18 22:14:31 +08:00
手瓜一十雪
b9f61cc0ee Add configurable bypass options and UI
Introduce granular "bypass" configuration to control Napi2Native bypass features and expose it in the WebUI.

Key changes:
- Add bypass defaults to packages/napcat-core/external/napcat.json and BypassOptionsSchema in napcat-core helper config.
- Extend Napi2NativeLoader types: enableAllBypasses now accepts BypassOptions.
- Framework & Shell: load napcat.json (via json5), pass parsed bypass options to native loader, and log the applied config. Add json5 dependency.
- Shell: implement loadBypassConfig with a crash-recovery override (NAPCAT_BYPASS_DISABLE_LEVEL) and add master<->worker IPC (login-success) plus progressive bypass-disable strategy to mitigate repeated crashes before login.
- WebUI backend: add GET/Set endpoints for NapCat config (NapCatConfigRouter) with validation and JSON5-aware defaults.
- WebUI frontend: add BypassConfig page, types, and controller methods to get/set bypass config.
- Update package.json to include json5 and update pnpm lockfile; native binaries (.node / ffmpeg.dll) also updated.

This enables operators to tune bypass behavior per-installation and to have an in-UI control for toggling anti-detection features; it also adds progressive fallback behavior to help recover from crashes caused by bypasses.
2026-02-18 22:09:27 +08:00
手瓜一十雪
9998207346 Move plugin data to config path; improve uninstall UI
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Change plugin data storage to use core.context.pathWrapper.configPath/plugins/<id> instead of pluginPath/data across OB11 plugin managers. Ensure plugin config directory is created when building the plugin context, use the central path for cleanup/uninstall, and update getPluginDataPath accordingly. Update web UI uninstall flow to prompt for cleaning configuration files using dialog.confirm (showing the config path) and performUninstall helper instead of window.confirm. Also include rebuilt native binaries (napi2native) for Linux x64 and arm64.
2026-02-18 16:49:43 +08:00
手瓜一十雪
4f47af233f Update napi2native Linux native binaries
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Replace prebuilt napi2native native modules for Linux (arm64 and x64) with updated binaries. These updated artifacts ensure the native addon is rebuilt and compatible with current Node/N-API/ABI or dependency changes, restoring compatibility and performance on Linux platforms.
2026-02-16 15:39:44 +08:00
手瓜一十雪
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
136 changed files with 6423 additions and 1447 deletions

View File

@@ -10,7 +10,7 @@ permissions: write-all
env:
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"
jobs:
@@ -396,7 +396,7 @@ jobs:
--arg system "$SYSTEM_PROMPT" \
--arg user "$USER_CONTENT" \
--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 "$BODY" | jq .

View File

@@ -5,47 +5,41 @@
_Modern protocol-side framework implemented based on NTQQ._
> 云起兮风生,心向远方兮路未曾至.
> Where clouds rise and winds are born, the heart yearns for distant lands yet untraveled.
English | [简体中文](./docs/README_zh-CN.md) | [繁體中文](./docs/README_zh-TW.md) | [日本語](./docs/README_ja.md) | [한국어](./docs/README_ko.md) | [Русский](./docs/README_ru.md) | [العربية](./docs/README_ar.md)
</div>
---
## New Feature
在 v4.8.115+ 版本开始
1. NapCatQQ 支持 [Stream Api](https://napneko.github.io/develop/file)
2. NapCatQQ 推荐 message_id/user_id/group_id 均使用字符串类型
- [1] 解决 Docker/跨设备/大文件 的多媒体上下传问题
- [2] 采用字符串可以解决扩展到int64的问题同时也可以解决部分语言如JavaScript对大整数支持不佳的问题增加极少成本。
## Notice
NapCat is currently looking for a new primary maintainer. Please email nanaeonn@outlook.com if you are interested. No public community groups will be established during this period, but NapCat will continue to receive regular updates.
## Welcome
- NapCatQQ is a modern implementation of the Bot protocol based on NTQQ.
- NapCatQQ 是现代化的基于 NTQQ 的 Bot 协议端实现
## Feature
## Features
- **Easy to Use**
- 作为初学者能够轻松使用.
- Beginners can get started effortlessly.
- **Quick and Efficient**
- 在低内存操作系统长时运行.
- Runs for extended periods on low-memory systems.
- **Rich API Interface**
- 完整实现了大部分标准接口.
- Fully implements most standard interfaces.
- **Stable and Reliable**
- 持续稳定的开发与维护.
- Continuous and stable development and maintenance.
## Quick Start
可前往 [Release](https://github.com/NapNeko/NapCatQQ/releases/) 页面下载最新版本
Download the latest version from the [Release](https://github.com/NapNeko/NapCatQQ/releases/) page.
**首次使用**请务必查看如下文档看使用教程
**First-time users** should make sure to read the documentation below for a usage guide.
> 项目非盈利,涉及 对接问题/基础问题/下层框架问题 请自行搜索解决,本项目社区不提供此类解答。
> This is a non-profit project. For integration issues, basic questions, or underlying framework issues, please search for solutions on your own — this project's community does not provide such support.
## Link
## Links
| Docs | [![Github.IO](https://img.shields.io/badge/docs%20on-Github.IO-orange)](https://napneko.github.io/) | [![Cloudflare.Worker](https://img.shields.io/badge/docs%20on-Cloudflare.Worker-black)](https://doc.napneko.icu/) | [![Cloudflare.HKServer](https://img.shields.io/badge/docs%20on-Cloudflare.HKServer-informational)](https://napcat.napneko.icu/) |
|:-:|:-:|:-:|:-:|
@@ -53,37 +47,31 @@ _Modern protocol-side framework implemented based on NTQQ._
| Docs | [![Cloudflare.Pages](https://img.shields.io/badge/docs%20on-Cloudflare.Pages-blue)](https://napneko.pages.dev/) | [![Server.Other](https://img.shields.io/badge/docs%20on-Server.Other-green)](https://napcat.top/) | [![NapCat.Top](https://img.shields.io/badge/docs%20on-NapCat.Top-red)](https://napcat.top/) |
|:-:|:-:|:-:|:-:|
| QQ Group | [![QQ Group#4](https://img.shields.io/badge/QQ%20Group%234-Join-blue)](https://qm.qq.com/q/CMmPbGw0jA) | [![QQ Group#3](https://img.shields.io/badge/QQ%20Group%233-Join-blue)](https://qm.qq.com/q/8zJMLjqy2Y) | [![QQ Group#2](https://img.shields.io/badge/QQ%20Group%232-Join-blue)](https://qm.qq.com/q/CMmPbGw0jA) | [![QQ Group#1](https://img.shields.io/badge/QQ%20Group%231-Join-blue)](https://qm.qq.com/q/I6LU87a0Yq) |
|:-:|:-:|:-:|:-:|:-:|
| Telegram | [![Telegram](https://img.shields.io/badge/Telegram-napcatqq-blue)](https://t.me/napcatqq) |
|:-:|:-:|
| DeepWiki | [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/NapNeko/NapCatQQ) |
|:-:|:-:|
> 请不要在其余社区提及本项目(包括其余协议端/相关应用端项目)引发争论,如有建议到达官方交流群讨论或PR
> Please do not mention this project in other communities (including other protocol-side or related application-side projects) to avoid disputes. If you have suggestions, please discuss them in the official group or submit a PR.
## Thanks
- [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 对本项目的大力支持 参考部分代码 已获授权
- [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) — Great support for this project; some code was referenced (with permission)
- [AstrBot](https://github.com/AstrBotDevs/AstrBot) 是完美适配本项目的LLM Bot框架 在此推荐一下
- [AstrBot](https://github.com/AstrBotDevs/AstrBot) — An LLM Bot framework that perfectly integrates with this project
- [MaiBot](https://github.com/MaiM-with-u/MaiBot) 一只赛博群友 麦麦 Bot框架 在此推荐一下
- [MaiBot](https://github.com/MaiM-with-u/MaiBot) — A cyber companion Bot framework
- [qq-chat-exporter](https://github.com/shuakami/qq-chat-exporter/) 基于NapCat的消息导出工具 在此推荐一下
- [qq-chat-exporter](https://github.com/shuakami/qq-chat-exporter/) — A message export tool based on NapCat
- 不过最最重要的 还是需要感谢屏幕前的你哦~
- And most importantly, thank you — the person reading this right now~
---
## License
本项目采用 混合协议 开源,因此使用本项目时,你需要注意以下几点:
This project is open-sourced under a hybrid license. When using this project, please note the following:
1. 第三方库代码或修改部分遵循其原始开源许可.
2. 本项目获取部分项目授权而不受部分约束
2. 项目其余逻辑代码采用[本仓库开源许可](./LICENSE).
1. Third-party library code or modified portions follow their original open-source licenses.
2. This project has obtained authorization from certain projects and is not subject to some restrictions.
3. The remaining logic code of the project is governed by the [repository license](./LICENSE).
**本仓库仅用于提高易用性,实现消息推送类功能,此外,禁止任何项目未经仓库主作者授权基于 NapCat 代码开发。使用请遵守当地法律法规,由此造成的问题由使用者和提供违规使用教程者负责。**
**This repository is solely intended to improve usability and implement message push features. Furthermore, developing any project based on NapCat code without prior authorization from the repository's main author is prohibited. Please comply with local laws and regulations when using this project. Any issues arising from misuse are the responsibility of the user and anyone providing tutorials for unauthorized use.**

81
docs/README_ar.md Normal file
View File

@@ -0,0 +1,81 @@
<div dir="rtl">
<img src="https://napneko.github.io/assets/newnewlogo.png" width = "305" height = "411" alt="NapCat" align=left />
<div align="center">
# NapCat
_إطار عمل حديث على جانب البروتوكول مبني على NTQQ._
> حيث تنهض السحب وتولد الرياح، يتوق القلب إلى أراضٍ بعيدة لم تُسلك بعد.
[English](../README.md) | [简体中文](./README_zh-CN.md) | [繁體中文](./README_zh-TW.md) | [日本語](./README_ja.md) | [한국어](./README_ko.md) | [Русский](./README_ru.md) | العربية
</div>
---
## إعلان
يبحث NapCat حالياً عن مشرف رئيسي جديد. يرجى التواصل عبر البريد الإلكتروني nanaeonn@outlook.com. لن يتم إنشاء مجموعات مجتمع عامة خلال هذه الفترة، لكن NapCat يضمن استمرار التحديثات المنتظمة.
## مرحباً
- NapCatQQ هو تطبيق حديث لبروتوكول Bot مبني على NTQQ
## المميزات
- **سهل الاستخدام**
- يمكن للمبتدئين البدء بسهولة.
- **سريع وفعال**
- يعمل لفترات طويلة على أنظمة ذات ذاكرة منخفضة.
- **واجهة API غنية**
- تنفيذ كامل لمعظم الواجهات القياسية.
- **مستقر وموثوق**
- تطوير وصيانة مستمرة ومستقرة.
## البداية السريعة
قم بتنزيل أحدث إصدار من صفحة [Release](https://github.com/NapNeko/NapCatQQ/releases/)
**للمستخدمين لأول مرة** تأكد من قراءة الوثائق أدناه للحصول على دليل الاستخدام
> هذا مشروع غير ربحي. للمشاكل المتعلقة بالتكامل والأسئلة الأساسية ومشاكل إطار العمل الأساسي، يرجى البحث عن الحلول بنفسك — مجتمع هذا المشروع لا يقدم مثل هذا الدعم.
## الروابط
| الوثائق | [![Github.IO](https://img.shields.io/badge/docs%20on-Github.IO-orange)](https://napneko.github.io/) | [![Cloudflare.Worker](https://img.shields.io/badge/docs%20on-Cloudflare.Worker-black)](https://doc.napneko.icu/) | [![Cloudflare.HKServer](https://img.shields.io/badge/docs%20on-Cloudflare.HKServer-informational)](https://napcat.napneko.icu/) |
|:-:|:-:|:-:|:-:|
| الوثائق | [![Cloudflare.Pages](https://img.shields.io/badge/docs%20on-Cloudflare.Pages-blue)](https://napneko.pages.dev/) | [![Server.Other](https://img.shields.io/badge/docs%20on-Server.Other-green)](https://napcat.top/) | [![NapCat.Top](https://img.shields.io/badge/docs%20on-NapCat.Top-red)](https://napcat.top/) |
|:-:|:-:|:-:|:-:|
| DeepWiki | [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/NapNeko/NapCatQQ) |
|:-:|:-:|
> يرجى عدم ذكر هذا المشروع في مجتمعات أخرى (بما في ذلك مشاريع البروتوكول الأخرى / مشاريع التطبيقات ذات الصلة) لتجنب الخلافات. إذا كانت لديك اقتراحات، يرجى مناقشتها في المجموعة الرسمية أو تقديم PR.
## شكر وتقدير
- [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) — دعم كبير لهذا المشروع؛ تمت الإشارة إلى بعض الأكواد (بإذن)
- [AstrBot](https://github.com/AstrBotDevs/AstrBot) — إطار عمل LLM Bot متوافق تماماً مع هذا المشروع
- [MaiBot](https://github.com/MaiM-with-u/MaiBot) — إطار عمل Bot رفيق سيبراني
- [qq-chat-exporter](https://github.com/shuakami/qq-chat-exporter/) — أداة تصدير الرسائل مبنية على NapCat
- والأهم من ذلك كله، شكراً لك — أنت الذي تقرأ هذا الآن~
---
## الرخصة
هذا المشروع مفتوح المصدر بموجب رخصة هجينة. عند استخدام هذا المشروع، يرجى ملاحظة ما يلي:
1. كود المكتبات الخارجية أو الأجزاء المعدلة تخضع لرخصها مفتوحة المصدر الأصلية.
2. حصل هذا المشروع على إذن من بعض المشاريع ولا يخضع لبعض القيود.
3. باقي الكود المنطقي للمشروع يخضع [لرخصة هذا المستودع](../LICENSE).
**هذا المستودع مخصص فقط لتحسين سهولة الاستخدام وتنفيذ ميزات دفع الرسائل. علاوة على ذلك، يُحظر تطوير أي مشروع بناءً على كود NapCat دون إذن مسبق من المؤلف الرئيسي للمستودع. يرجى الامتثال للقوانين واللوائح المحلية عند الاستخدام. أي مشاكل ناتجة عن سوء الاستخدام تقع على عاتق المستخدم ومن يقدم تعليمات الاستخدام غير المصرح به.**
</div>

77
docs/README_ja.md Normal file
View File

@@ -0,0 +1,77 @@
<img src="https://napneko.github.io/assets/newnewlogo.png" width = "305" height = "411" alt="NapCat" align=right />
<div align="center">
# NapCat
_NTQQをベースにした最新のプロトコル側フレームワーク._
> 雲起きて風生じ、心は遠方を向けど路は未だ至らず.
[English](../README.md) | [简体中文](./README_zh-CN.md) | [繁體中文](./README_zh-TW.md) | 日本語 | [한국어](./README_ko.md) | [Русский](./README_ru.md) | [العربية](./README_ar.md)
</div>
---
## お知らせ
NapCat は現在、新しいメインメンテナーを募集しています。nanaeonn@outlook.com までメールでご連絡ください。この期間中、公開コミュニティグループは設立しませんが、NapCat は通常通りの更新を保証します。
## ようこそ
- NapCatQQ は NTQQ をベースにした最新の Bot プロトコル側実装です
## 特徴
- **簡単に使える**
- 初心者でも簡単に使用できます.
- **高速で効率的**
- 低メモリ環境のOSで長時間稼働できます.
- **豊富な API インターフェース**
- ほとんどの標準インターフェースを完全に実装しています.
- **安定して信頼できる**
- 継続的で安定した開発とメンテナンスを行っています.
## クイックスタート
最新バージョンは [Release](https://github.com/NapNeko/NapCatQQ/releases/) ページからダウンロードできます
**初めてご使用の方**は、以下のドキュメントで使用ガイドを必ずご確認ください
> このプロジェクトは非営利です。連携に関する問題/基本的な問題/下位フレームワークの問題については、ご自身で検索して解決してください。本プロジェクトのコミュニティではそのような回答は提供していません。
## リンク
| ドキュメント | [![Github.IO](https://img.shields.io/badge/docs%20on-Github.IO-orange)](https://napneko.github.io/) | [![Cloudflare.Worker](https://img.shields.io/badge/docs%20on-Cloudflare.Worker-black)](https://doc.napneko.icu/) | [![Cloudflare.HKServer](https://img.shields.io/badge/docs%20on-Cloudflare.HKServer-informational)](https://napcat.napneko.icu/) |
|:-:|:-:|:-:|:-:|
| ドキュメント | [![Cloudflare.Pages](https://img.shields.io/badge/docs%20on-Cloudflare.Pages-blue)](https://napneko.pages.dev/) | [![Server.Other](https://img.shields.io/badge/docs%20on-Server.Other-green)](https://napcat.top/) | [![NapCat.Top](https://img.shields.io/badge/docs%20on-NapCat.Top-red)](https://napcat.top/) |
|:-:|:-:|:-:|:-:|
| DeepWiki | [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/NapNeko/NapCatQQ) |
|:-:|:-:|
> 他のコミュニティでこのプロジェクト(他のプロトコル側/関連アプリケーション側のプロジェクトを含むに言及して論争を引き起こさないでください。提案がある場合は、公式交流グループで議論するか、PRを提出してください。
## 謝辞
- [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 本プロジェクトへの多大なサポート、一部コードを参考にしています(許可済み)
- [AstrBot](https://github.com/AstrBotDevs/AstrBot) 本プロジェクトに完璧に対応した LLM Bot フレームワークです
- [MaiBot](https://github.com/MaiM-with-u/MaiBot) サイバー仲間の 麦麦 Bot フレームワークです
- [qq-chat-exporter](https://github.com/shuakami/qq-chat-exporter/) NapCat ベースのメッセージエクスポートツールです
- そして何より大切なのは、画面の前のあなたに感謝することです~
---
## ライセンス
本プロジェクトはハイブリッドライセンスの下でオープンソース化されています。本プロジェクトを使用する際は、以下の点にご注意ください:
1. サードパーティライブラリのコードまたは修正部分は、元のオープンソースライセンスに従います.
2. 本プロジェクトは一部のプロジェクトから許可を得ており、一部の制約を受けません.
3. プロジェクトのその他のロジックコードは[本リポジトリのオープンソースライセンス](../LICENSE)に従います.
**本リポジトリは使いやすさの향上とメッセージプッシュ機能の実装のみを目的としています。また、リポジトリの主要作者の事前許可なく NapCat のコードに基づいてプロジェクトを開発することは禁止されています。使用する際は現地の法律と規制を遵守してください。これに起因する問題は、使用者および違反使用チュートリアルの提供者の責任となります。**

77
docs/README_ko.md Normal file
View File

@@ -0,0 +1,77 @@
<img src="https://napneko.github.io/assets/newnewlogo.png" width = "305" height = "411" alt="NapCat" align=right />
<div align="center">
# NapCat
_NTQQ 기반으로 구현된 최신 프로토콜 사이드 프레임워크._
> 구름이 일고 바람이 불어, 마음은 먼 곳을 향하나 길은 아직 닿지 못했네.
[English](../README.md) | [简体中文](./README_zh-CN.md) | [繁體中文](./README_zh-TW.md) | [日本語](./README_ja.md) | 한국어 | [Русский](./README_ru.md) | [العربية](./README_ar.md)
</div>
---
## 공지
NapCat은 현재 새로운 주요 메인테이너를 찾고 있습니다. nanaeonn@outlook.com 으로 이메일을 보내주세요. 이 기간 동안 공개 커뮤니티 그룹은 만들어지지 않지만, NapCat은 정기적인 업데이트를 보장합니다.
## 환영합니다
- NapCatQQ는 NTQQ를 기반으로 한 최신 Bot 프로토콜 구현체입니다
## 특징
- **사용하기 쉬움**
- 초보자도 쉽게 사용할 수 있습니다.
- **빠르고 효율적**
- 저메모리 시스템에서도 장시간 안정적으로 실행됩니다.
- **풍부한 API 인터페이스**
- 대부분의 표준 인터페이스를 완전히 구현했습니다.
- **안정적이고 신뢰할 수 있음**
- 지속적이고 안정적인 개발과 유지보수를 하고 있습니다.
## 빠른 시작
[Release](https://github.com/NapNeko/NapCatQQ/releases/) 페이지에서 최신 버전을 다운로드할 수 있습니다
**처음 사용하시는 분**은 아래 문서에서 사용 가이드를 반드시 확인해 주세요
> 이 프로젝트는 비영리입니다. 연동 문제/기본 문제/하위 프레임워크 문제는 직접 검색하여 해결해 주세요. 본 프로젝트 커뮤니티에서는 이러한 지원을 제공하지 않습니다.
## 링크
| 문서 | [![Github.IO](https://img.shields.io/badge/docs%20on-Github.IO-orange)](https://napneko.github.io/) | [![Cloudflare.Worker](https://img.shields.io/badge/docs%20on-Cloudflare.Worker-black)](https://doc.napneko.icu/) | [![Cloudflare.HKServer](https://img.shields.io/badge/docs%20on-Cloudflare.HKServer-informational)](https://napcat.napneko.icu/) |
|:-:|:-:|:-:|:-:|
| 문서 | [![Cloudflare.Pages](https://img.shields.io/badge/docs%20on-Cloudflare.Pages-blue)](https://napneko.pages.dev/) | [![Server.Other](https://img.shields.io/badge/docs%20on-Server.Other-green)](https://napcat.top/) | [![NapCat.Top](https://img.shields.io/badge/docs%20on-NapCat.Top-red)](https://napcat.top/) |
|:-:|:-:|:-:|:-:|
| DeepWiki | [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/NapNeko/NapCatQQ) |
|:-:|:-:|
> 다른 커뮤니티에서 이 프로젝트(다른 프로토콜 측/관련 애플리케이션 측 프로젝트 포함)를 언급하여 논쟁을 일으키지 마세요. 제안이 있으시면 공식 그룹에서 토론하거나 PR을 제출해 주세요.
## 감사의 말
- [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) — 본 프로젝트에 대한 큰 지원, 일부 코드 참고 (허가 완료)
- [AstrBot](https://github.com/AstrBotDevs/AstrBot) — 본 프로젝트와 완벽하게 호환되는 LLM Bot 프레임워크
- [MaiBot](https://github.com/MaiM-with-u/MaiBot) — 사이버 친구 麦麦 Bot 프레임워크
- [qq-chat-exporter](https://github.com/shuakami/qq-chat-exporter/) — NapCat 기반의 메시지 내보내기 도구
- 그리고 가장 중요한 것은, 지금 이 글을 읽고 있는 당신에게 감사드립니다~
---
## 라이선스
이 프로젝트는 하이브리드 라이선스로 오픈소스화되어 있습니다. 이 프로젝트를 사용할 때 다음 사항에 유의해 주세요:
1. 서드파티 라이브러리 코드 또는 수정된 부분은 원래의 오픈소스 라이선스를 따릅니다.
2. 이 프로젝트는 일부 프로젝트로부터 허가를 받아 일부 제한을 받지 않습니다.
3. 프로젝트의 나머지 로직 코드는 [본 리포지토리 라이선스](../LICENSE)를 따릅니다.
**이 리포지토리는 사용 편의성 향상과 메시지 푸시 기능 구현만을 목적으로 합니다. 또한, 리포지토리 주요 작성자의 사전 승인 없이 NapCat 코드를 기반으로 프로젝트를 개발하는 것은 금지되어 있습니다. 사용 시 현지 법률 및 규정을 준수해 주세요. 이로 인해 발생하는 문제는 사용자 및 위반 사용 튜토리얼 제공자의 책임입니다.**

77
docs/README_ru.md Normal file
View File

@@ -0,0 +1,77 @@
<img src="https://napneko.github.io/assets/newnewlogo.png" width = "305" height = "411" alt="NapCat" align=right />
<div align="center">
# NapCat
_Современный фреймворк на стороне протокола, реализованный на базе NTQQ._
> Облака поднимаются, ветер рождается, сердце стремится вдаль, но путь ещё не пройден.
[English](../README.md) | [简体中文](./README_zh-CN.md) | [繁體中文](./README_zh-TW.md) | [日本語](./README_ja.md) | [한국어](./README_ko.md) | Русский | [العربية](./README_ar.md)
</div>
---
## Объявление
NapCat в настоящее время ищет нового основного мейнтейнера. Пожалуйста, свяжитесь с нами по электронной почте nanaeonn@outlook.com. В этот период публичные группы сообщества создаваться не будут, но NapCat гарантирует регулярные обновления.
## Добро пожаловать
- NapCatQQ — это современная реализация протокола Bot на базе NTQQ
## Особенности
- **Простота использования**
- Начинающие пользователи смогут легко освоить работу.
- **Скорость и эффективность**
- Длительная работа на системах с ограниченным объёмом памяти.
- **Богатый API-интерфейс**
- Полная реализация большинства стандартных интерфейсов.
- **Стабильность и надёжность**
- Постоянная стабильная разработка и поддержка.
## Быстрый старт
Скачайте последнюю версию на странице [Release](https://github.com/NapNeko/NapCatQQ/releases/)
**При первом использовании** обязательно ознакомьтесь с руководством в документации ниже
> Проект является некоммерческим. Вопросы интеграции, базовые вопросы и вопросы по нижележащему фреймворку решайте самостоятельно — сообщество данного проекта не предоставляет такой поддержки.
## Ссылки
| Документация | [![Github.IO](https://img.shields.io/badge/docs%20on-Github.IO-orange)](https://napneko.github.io/) | [![Cloudflare.Worker](https://img.shields.io/badge/docs%20on-Cloudflare.Worker-black)](https://doc.napneko.icu/) | [![Cloudflare.HKServer](https://img.shields.io/badge/docs%20on-Cloudflare.HKServer-informational)](https://napcat.napneko.icu/) |
|:-:|:-:|:-:|:-:|
| Документация | [![Cloudflare.Pages](https://img.shields.io/badge/docs%20on-Cloudflare.Pages-blue)](https://napneko.pages.dev/) | [![Server.Other](https://img.shields.io/badge/docs%20on-Server.Other-green)](https://napcat.top/) | [![NapCat.Top](https://img.shields.io/badge/docs%20on-NapCat.Top-red)](https://napcat.top/) |
|:-:|:-:|:-:|:-:|
| DeepWiki | [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/NapNeko/NapCatQQ) |
|:-:|:-:|
> Пожалуйста, не упоминайте данный проект (включая другие протокольные/прикладные проекты) в других сообществах во избежание споров. Если у вас есть предложения, обсуждайте их в официальной группе или отправляйте PR.
## Благодарности
- [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) — большая поддержка данного проекта, частично использован код (с разрешения)
- [AstrBot](https://github.com/AstrBotDevs/AstrBot) — фреймворк LLM Bot, идеально совместимый с данным проектом
- [MaiBot](https://github.com/MaiM-with-u/MaiBot) — кибер-друг 麦麦, Bot-фреймворк
- [qq-chat-exporter](https://github.com/shuakami/qq-chat-exporter/) — инструмент экспорта сообщений на базе NapCat
- И самое главное — спасибо вам, читающему это~
---
## Лицензия
Данный проект распространяется с открытым исходным кодом под гибридной лицензией. При использовании данного проекта обратите внимание на следующее:
1. Код сторонних библиотек или модифицированные части подчиняются их исходным лицензиям с открытым исходным кодом.
2. Данный проект получил разрешение от ряда проектов и не подчиняется некоторым ограничениям.
3. Остальной логический код проекта распространяется по [лицензии данного репозитория](../LICENSE).
**Данный репозиторий предназначен исключительно для повышения удобства использования и реализации функций отправки сообщений. Кроме того, запрещается разработка проектов на основе кода NapCat без предварительного разрешения главного автора репозитория. При использовании соблюдайте местное законодательство. За любые проблемы, вызванные нарушением, несут ответственность пользователь и лицо, предоставившее инструкции по незаконному использованию.**

77
docs/README_zh-CN.md Normal file
View File

@@ -0,0 +1,77 @@
<img src="https://napneko.github.io/assets/newnewlogo.png" width = "305" height = "411" alt="NapCat" align=right />
<div align="center">
# NapCat
_基于 NTQQ 实现的现代化协议端框架._
> 云起兮风生,心向远方兮路未曾至.
[English](../README.md) | 简体中文 | [繁體中文](./README_zh-TW.md) | [日本語](./README_ja.md) | [한국어](./README_ko.md) | [Русский](./README_ru.md) | [العربية](./README_ar.md)
</div>
---
## 公告
NapCat 当前正在寻找新的主要维护者欢迎email到 nanaeonn@outlook.com 在此期不会建立任何公开社区交流群Napcat会保证此期间的正常更新。
## 欢迎
- NapCatQQ 是现代化的基于 NTQQ 的 Bot 协议端实现
## 特性
- **易于使用**
- 作为初学者能够轻松使用.
- **快速高效**
- 在低内存操作系统长时运行.
- **丰富的 API 接口**
- 完整实现了大部分标准接口.
- **稳定可靠**
- 持续稳定的开发与维护.
## 快速开始
可前往 [Release](https://github.com/NapNeko/NapCatQQ/releases/) 页面下载最新版本
**首次使用**请务必查看如下文档看使用教程
> 项目非盈利,涉及 对接问题/基础问题/下层框架问题 请自行搜索解决,本项目社区不提供此类解答。
## 链接
| 文档 | [![Github.IO](https://img.shields.io/badge/docs%20on-Github.IO-orange)](https://napneko.github.io/) | [![Cloudflare.Worker](https://img.shields.io/badge/docs%20on-Cloudflare.Worker-black)](https://doc.napneko.icu/) | [![Cloudflare.HKServer](https://img.shields.io/badge/docs%20on-Cloudflare.HKServer-informational)](https://napcat.napneko.icu/) |
|:-:|:-:|:-:|:-:|
| 文档 | [![Cloudflare.Pages](https://img.shields.io/badge/docs%20on-Cloudflare.Pages-blue)](https://napneko.pages.dev/) | [![Server.Other](https://img.shields.io/badge/docs%20on-Server.Other-green)](https://napcat.top/) | [![NapCat.Top](https://img.shields.io/badge/docs%20on-NapCat.Top-red)](https://napcat.top/) |
|:-:|:-:|:-:|:-:|
| DeepWiki | [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/NapNeko/NapCatQQ) |
|:-:|:-:|
> 请不要在其余社区提及本项目(包括其余协议端/相关应用端项目)引发争论如有建议到达官方交流群讨论或PR。
## 致谢
- [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 对本项目的大力支持 参考部分代码 已获授权
- [AstrBot](https://github.com/AstrBotDevs/AstrBot) 是完美适配本项目的LLM Bot框架 在此推荐一下
- [MaiBot](https://github.com/MaiM-with-u/MaiBot) 一只赛博群友 麦麦 Bot框架 在此推荐一下
- [qq-chat-exporter](https://github.com/shuakami/qq-chat-exporter/) 基于NapCat的消息导出工具 在此推荐一下
- 不过最最重要的 还是需要感谢屏幕前的你哦~
---
## 许可证
本项目采用 混合协议 开源,因此使用本项目时,你需要注意以下几点:
1. 第三方库代码或修改部分遵循其原始开源许可.
2. 本项目获取部分项目授权而不受部分约束
2. 项目其余逻辑代码采用[本仓库开源许可](../LICENSE).
**本仓库仅用于提高易用性,实现消息推送类功能,此外,禁止任何项目未经仓库主作者授权基于 NapCat 代码开发。使用请遵守当地法律法规,由此造成的问题由使用者和提供违规使用教程者负责。**

77
docs/README_zh-TW.md Normal file
View File

@@ -0,0 +1,77 @@
<img src="https://napneko.github.io/assets/newnewlogo.png" width = "305" height = "411" alt="NapCat" align=right />
<div align="center">
# NapCat
_基於 NTQQ 實現的現代化協議端框架._
> 雲起兮風生,心向遠方兮路未曾至.
[English](../README.md) | [简体中文](./README_zh-CN.md) | 繁體中文 | [日本語](./README_ja.md) | [한국어](./README_ko.md) | [Русский](./README_ru.md) | [العربية](./README_ar.md)
</div>
---
## 公告
NapCat 目前正在尋找新的主要維護者,歡迎透過 email 聯繫 nanaeonn@outlook.com。在此期間不會建立任何公開社群交流群NapCat 會保證此期間的正常更新。
## 歡迎
- NapCatQQ 是現代化的基於 NTQQ 的 Bot 協議端實現
## 特性
- **易於使用**
- 初學者也能輕鬆上手.
- **快速高效**
- 在低記憶體系統長時間穩定運行.
- **豐富的 API 介面**
- 完整實現了大部分標準介面.
- **穩定可靠**
- 持續穩定的開發與維護.
## 快速開始
可前往 [Release](https://github.com/NapNeko/NapCatQQ/releases/) 頁面下載最新版本
**首次使用**請務必查看以下文件中的使用教學
> 專案為非營利性質,涉及 對接問題/基礎問題/底層框架問題 請自行搜尋解決,本專案社群不提供此類解答。
## 連結
| 文件 | [![Github.IO](https://img.shields.io/badge/docs%20on-Github.IO-orange)](https://napneko.github.io/) | [![Cloudflare.Worker](https://img.shields.io/badge/docs%20on-Cloudflare.Worker-black)](https://doc.napneko.icu/) | [![Cloudflare.HKServer](https://img.shields.io/badge/docs%20on-Cloudflare.HKServer-informational)](https://napcat.napneko.icu/) |
|:-:|:-:|:-:|:-:|
| 文件 | [![Cloudflare.Pages](https://img.shields.io/badge/docs%20on-Cloudflare.Pages-blue)](https://napneko.pages.dev/) | [![Server.Other](https://img.shields.io/badge/docs%20on-Server.Other-green)](https://napcat.top/) | [![NapCat.Top](https://img.shields.io/badge/docs%20on-NapCat.Top-red)](https://napcat.top/) |
|:-:|:-:|:-:|:-:|
| DeepWiki | [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/NapNeko/NapCatQQ) |
|:-:|:-:|
> 請不要在其他社群提及本專案(包括其他協議端/相關應用端專案)以免引發爭論。如有建議,請到官方交流群討論或提交 PR。
## 致謝
- [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 對本專案的大力支持,參考部分程式碼(已獲授權)
- [AstrBot](https://github.com/AstrBotDevs/AstrBot) 是完美適配本專案的 LLM Bot 框架,在此推薦
- [MaiBot](https://github.com/MaiM-with-u/MaiBot) 一隻賽博群友 麥麥 Bot 框架,在此推薦
- [qq-chat-exporter](https://github.com/shuakami/qq-chat-exporter/) 基於 NapCat 的訊息匯出工具,在此推薦
- 不過最最重要的,還是要感謝螢幕前的你哦~
---
## 授權條款
本專案採用混合協議開源,因此使用本專案時,您需要注意以下幾點:
1. 第三方函式庫程式碼或修改部分遵循其原始開源授權.
2. 本專案已獲取部分專案授權而不受部分約束.
3. 專案其餘邏輯程式碼採用[本倉庫開源授權](../LICENSE).
**本倉庫僅用於提高易用性,實現訊息推送類功能,此外,禁止任何專案未經倉庫主作者授權基於 NapCat 程式碼開發。使用請遵守當地法律法規,由此造成的問題由使用者和提供違規使用教學者負責。**

View File

@@ -68,7 +68,7 @@ export class NTQQPacketApi {
this.pkt = new PacketClientSession(this.core);
await this.pkt.init(process.pid, table.recv, table.send);
try {
await this.pkt.operation.FetchRkey(1500);
await this.pkt.operation.FetchRkey(3000);
} catch (error) {
this.logger.logError('测试Packet状态异常', error);
return false;

View File

@@ -5,5 +5,13 @@
"consoleLogLevel": "info",
"packetBackend": "auto",
"packetServer": "",
"o3HookMode": 1
"o3HookMode": 1,
"bypass": {
"hook": false,
"window": false,
"module": false,
"process": false,
"container": false,
"js": false
}
}

View File

@@ -1,7 +1,19 @@
import { ConfigBase } from '@/napcat-core/helper/config-base';
import { NapCatCore } from '@/napcat-core/index';
import { Type, Static } from '@sinclair/typebox';
import { AnySchema } from 'ajv';
import Ajv, { AnySchema } from 'ajv';
import path from 'node:path';
import fs from 'node:fs';
import json5 from 'json5';
export const BypassOptionsSchema = Type.Object({
hook: Type.Boolean({ default: true }),
window: Type.Boolean({ default: true }),
module: Type.Boolean({ default: true }),
process: Type.Boolean({ default: true }),
container: Type.Boolean({ default: true }),
js: Type.Boolean({ default: true }),
});
export const NapcatConfigSchema = Type.Object({
fileLog: Type.Boolean({ default: false }),
@@ -11,10 +23,31 @@ export const NapcatConfigSchema = Type.Object({
packetBackend: Type.String({ default: 'auto' }),
packetServer: Type.String({ default: '' }),
o3HookMode: Type.Number({ default: 0 }),
bypass: Type.Optional(BypassOptionsSchema),
});
export type NapcatConfig = Static<typeof NapcatConfigSchema>;
/**
* 从指定配置目录读取 napcat.json按 NapcatConfigSchema 校验并填充默认值
* 用于登录前(无 NapCatCore 实例时)的早期配置读取
*/
export function loadNapcatConfig (configPath: string): NapcatConfig {
const ajv = new Ajv({ useDefaults: true, coerceTypes: true });
const validate = ajv.compile<NapcatConfig>(NapcatConfigSchema);
let data: Record<string, unknown> = {};
try {
const configFile = path.join(configPath, 'napcat.json');
if (fs.existsSync(configFile)) {
data = json5.parse(fs.readFileSync(configFile, 'utf-8'));
}
} catch {
// 读取失败时使用 schema 默认值
}
validate(data);
return data as NapcatConfig;
}
export class NapCatConfigLoader extends ConfigBase<NapcatConfig> {
constructor (core: NapCatCore, configPath: string, schema: AnySchema) {
super('napcat', core, configPath, schema);

View File

@@ -33,6 +33,7 @@ import { NodeIKernelMsgListener, NodeIKernelProfileListener } from '@/napcat-cor
import { proxiedListenerOf } from '@/napcat-core/helper/proxy-handler';
import { NTQQPacketApi } from './apis/packet';
import { NativePacketHandler } from './packet/handler/client';
import { Napi2NativeLoader } from './packet/handler/napi2nativeLoader';
import { container, ReceiverServiceRegistry } from './packet/handler/serviceRegister';
import { appEvent } from './packet/handler/eventList';
import { TypedEventEmitter } from './packet/handler/typeEvent';
@@ -314,6 +315,7 @@ export interface InstanceContext {
readonly basicInfoWrapper: QQBasicInfoWrapper;
readonly pathWrapper: NapCatPathWrapper;
readonly packetHandler: NativePacketHandler;
readonly napi2nativeLoader: Napi2NativeLoader;
}
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 { NapCoreContext } from '@/napcat-core/packet/context/napCoreContext';
import { PacketLogger } from '@/napcat-core/packet/context/loggerContext';
import { OidbPacket, PacketBuf } from '@/napcat-core/packet/transformer/base';
import { Napi2NativeLoader } from '@/napcat-core/packet/handler/napi2nativeLoader';
export interface RecvPacket {
type: string, // 仅recv
data: RecvPacketData;
@@ -17,50 +14,38 @@ export interface RecvPacketData {
data: Buffer;
}
// 0 send 1 recv
export interface NativePacketExportType {
initHook?: (send: string, recv: string) => boolean;
}
export class NativePacketClient {
protected readonly napcore: NapCoreContext;
protected readonly logger: PacketLogger;
protected readonly cb = new Map<string, (json: RecvPacketData) => Promise<any> | any>(); // hash-type callback
protected readonly napi2nativeLoader: Napi2NativeLoader;
logStack: LogStack;
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.logger = logger;
this.logStack = logStack;
this.napi2nativeLoader = napi2nativeLoader;
}
check (): boolean {
const platform = process.platform + '.' + process.arch;
if (!this.supportedPlatforms.includes(platform)) {
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}`);
if (!this.napi2nativeLoader.loaded) {
this.logStack.pushLogWarn('NativePacketClient: Napi2NativeLoader 未成功加载');
return false;
}
return true;
}
async init (_pid: number, recv: string, send: string): Promise<void> {
const platform = process.platform + '.' + process.arch;
const isNewQQ = this.napcore.basicInfo.requireMinNTQQBuild('40824');
if (isNewQQ) {
const moehoo_path = path.join(dirname(fileURLToPath(import.meta.url)), './native/napi2native/napi2native.' + platform + '.node');
process.dlopen(this.MoeHooExport, moehoo_path, constants.dlopen.RTLD_LAZY);
this.MoeHooExport?.exports.initHook?.(send, recv);
const success = this.napi2nativeLoader.initHook(send, recv);
if (success) {
this.available = true;
}
}
}
async sendPacket (
cmd: string,

View File

@@ -2,6 +2,7 @@ import { NativePacketClient } from '@/napcat-core/packet/client/nativeClient';
import { OidbPacket } from '@/napcat-core/packet/transformer/base';
import { PacketLogger } from '@/napcat-core/packet/context/loggerContext';
import { NapCoreContext } from '@/napcat-core/packet/context/napCoreContext';
import { Napi2NativeLoader } from '@/napcat-core/packet/handler/napi2nativeLoader';
export class LogStack {
private stack: string[] = [];
@@ -43,12 +44,14 @@ export class PacketClientContext {
private readonly napCore: NapCoreContext;
private readonly logger: PacketLogger;
private readonly logStack: LogStack;
private readonly napi2nativeLoader: Napi2NativeLoader;
private readonly _client: NativePacketClient;
constructor (napCore: NapCoreContext, logger: PacketLogger) {
constructor (napCore: NapCoreContext, logger: PacketLogger, napi2nativeLoader: Napi2NativeLoader) {
this.napCore = napCore;
this.logger = logger;
this.logStack = new LogStack(logger);
this.napi2nativeLoader = napi2nativeLoader;
this._client = this.newClient();
}
@@ -71,7 +74,7 @@ export class PacketClientContext {
private newClient (): 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()) {
throw new Error('[Core] [Packet] NativePacketClient 不可用NapCat.Packet将不会加载');
}

View File

@@ -34,5 +34,9 @@ export class NapCoreContext {
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);
}

View File

@@ -18,7 +18,7 @@ export class PacketContext {
this.msgConverter = new PacketMsgConverter();
this.napcore = new NapCoreContext(core);
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.operation = new PacketOperationContext(this);
}

View File

@@ -194,7 +194,7 @@ export class NativePacketHandler {
}
}
async init (version: string): Promise<boolean> {
async init (version: string, o3HookMode: boolean = false): Promise<boolean> {
const version_arch = version + '-' + process.arch;
try {
if (!this.loaded) {
@@ -215,7 +215,7 @@ export class NativePacketHandler {
this.MoeHooExport.exports.initHook?.(send, recv, (type: PacketType, uin: string, cmd: string, seq: number, hex_data: string) => {
this.emitPacket(type, uin, cmd, seq, hex_data);
}, true);
}, o3HookMode);
this.logger.log('[PacketHandler] 初始化成功');
return true;
} catch (error) {

View File

@@ -0,0 +1,90 @@
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 BypassOptions {
hook?: boolean;
window?: boolean;
module?: boolean;
process?: boolean;
container?: boolean;
js?: boolean;
}
export interface Napi2NativeExportType {
initHook?: (send: string, recv: string) => boolean;
setVerbose?: (verbose: boolean) => void; // 默认关闭日志
enableAllBypasses?: (options?: BypassOptions) => boolean;
}
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 {
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: {
qun_id: string,
attach_info: string,
seq: number,
request_time_line: {
request_invoke_time: string
}
request_invoke_time: string;
};
}): Promise<{
response: {
seq: number,
@@ -21,22 +21,22 @@ export interface NodeIKernelAlbumService {
trace_id: string,
is_from_cache: boolean,
request_time_line: unknown,
album_list: Array<{ name: string, album_id: string }>,
album_list: Array<{ name: string, album_id: string; }>,
attach_info: string,
has_more: boolean,
right: unknown,
banner: unknown
}
}>
getAlbumInfo(...args: unknown[]): unknown;// needs 1 arguments
banner: unknown;
};
}>;
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
modifyAlbum(...args: unknown[]): unknown;// needs 3 arguments
modifyAlbum (arg1: number, arg2: unknown, arg3: Array<unknown>[]): unknown;// needs 3 arguments
getMediaList (param: AlbumListRequest): Promise<{
response: {
@@ -45,33 +45,33 @@ export interface NodeIKernelAlbumService {
errMs: string, // 没错就是errMs不是errMsg
trace_id: string,
request_time_line: unknown,
}
};
}>;// 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
// stCommonExt {"map_info":[],"map_bytes_info":[],"map_user_account":[]}
// qunId string
doQunComment (seq: number, ext: {
map_info: unknown[],
map_bytes_info: unknown[],
map_user_account: unknown[]
map_user_account: unknown[];
},
qunId: string,
commentType: number,
@@ -79,23 +79,23 @@ export interface NodeIKernelAlbumService {
content: AlbumCommentReplyContent,
): 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 (
seq: number,
ext: {
map_info: unknown[],
map_bytes_info: unknown[],
map_user_account: unknown[]
map_user_account: unknown[];
},
param: {
// {"id":"421_1_0_1012959257|V61Yiali4PELg90bThrH4Bo2iI1M5Kab|V5bCgAxMDEyOTU5MjU3e*KqaLVYdic!^||^421_1_0_1012959257|V61Yiali4PELg90bThrH4Bo2iI1M5Kab|17560336594^||^1","status":1}
id: string,
status: number
status: number;
},
like: AlbumFeedLikePublish
): 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;
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;

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; }>;
checkIsBuddyAsync (uid: string): Promise<unknown>;
areBuddies (callFrom: string, uids: string[]): unknown;
getCategoryById (id: number): unknown;
addCategoryV2 (name: string, buddyUids?: unknown): Promise<unknown>;
isNull (): boolean;
getAddFriendBlockedList (): unknown;
getAddFriendBlockedRedPoint (): unknown;
reportAddFriendBlocked (): unknown;
setWXMsgNotify (arg: unknown): unknown;
}

View File

@@ -1,7 +1,7 @@
import { GeneralCallResult } from './common';
export interface NodeIKernelCollectionService {
addKernelCollectionListener(...args: unknown[]): void;// needs 1 arguments
addKernelCollectionListener (listener: unknown): void;// needs 1 arguments
removeKernelCollectionListener (listenerId: number): void;
@@ -12,7 +12,7 @@ export interface NodeIKernelCollectionService {
forceFromDb: boolean,
timeStamp: string,
count: number,
searchDown: boolean
searchDown: boolean;
}): Promise<GeneralCallResult &
{
collectionSearchList: {
@@ -27,7 +27,7 @@ export interface NodeIKernelCollectionService {
strId: string,
groupId: string,
groupName: string,
uid: string
uid: string;
},
bid: number,
category: number,
@@ -47,45 +47,45 @@ export interface NodeIKernelCollectionService {
fileSummary: unknown,
locationSummary: unknown,
richMediaSummary: unknown,
}
};
}>,
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 {
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 {
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

@@ -11,15 +11,15 @@ export interface NodeIKernelFileAssistantService {
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;
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;
@@ -31,7 +31,11 @@ export interface NodeIKernelFileAssistantService {
saveAs (arg1: unknown, arg2: unknown): unknown;
saveAsWithRename(arg1: unknown, arg2: unknown, arg3: unknown): unknown;
saveAsWithRename (arg1: string, arg2: string, arg3: string): unknown;
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;
}>; // 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 的信息
@@ -50,11 +50,11 @@ export interface NodeIKernelFlashTransferService {
rsp: FileListResponse;
}>; // 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;
}>; // 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 !!
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
*/
startFileSetUpload (fileSetId: string): void; // 1 arg 并不是新建任务,应该是暂停后的启动
startFileSetUpload (fileSetId: unknown): void; // 1 arg 并不是新建任务,应该是暂停后的启动
/**
* 结束,无法再次启动
@@ -110,27 +110,27 @@ export interface NodeIKernelFlashTransferService {
* 继续上传
* @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的函数 同开始上传
@@ -154,13 +154,13 @@ export interface NodeIKernelFlashTransferService {
extraInfo: 0;
}>; // 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 // 缩略图下载
@@ -174,31 +174,31 @@ export interface NodeIKernelFlashTransferService {
expireTimestampSeconds: string;
}>; // 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
@@ -211,9 +211,9 @@ export interface NodeIKernelFlashTransferService {
};
}>; // 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
@@ -227,77 +227,77 @@ export interface NodeIKernelFlashTransferService {
};
}>; // 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

@@ -20,8 +20,8 @@ export interface NodeIKernelGroupService {
{
result: {
groupCode: string,
result: number
}
result: number;
};
}>;
// --->
@@ -32,7 +32,7 @@ export interface NodeIKernelGroupService {
getAllGroupPrivilegeFlag (troopUinList: string[], serviceType: number): Promise<unknown>;
// <---
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>;
@@ -54,25 +54,25 @@ export interface NodeIKernelGroupService {
memberNum: number,
filterMethod: string,
onlineFlag: string,
realSpecialTitleFlag: number
realSpecialTitleFlag: number;
}): Promise<unknown>;
getGroupMemberLevelInfo (groupCode: string): 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<{
errCode: number,
errMsg: string,
uins: Map<string, string>
uins: Map<string, string>;
}>;
getUidByUins (uins: string[]): Promise<{
errCode: number,
errMsg: string,
uids: Map<string, string>
uids: Map<string, string>;
}>;
checkGroupMemberCache (arrayList: Array<string>): Promise<unknown>;
@@ -86,7 +86,7 @@ export interface NodeIKernelGroupService {
recvUin: string,
sendType: number,
clientInfo: {
platform: number
platform: number;
},
richMsg: {
usingArk: boolean,
@@ -94,19 +94,19 @@ export interface NodeIKernelGroupService {
summary: string,
url: string,
pictureUrl: string,
brief: string
}
brief: string;
};
}): 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: {
groupCode: string,
pageStart: number,
pageLimit: number
}, Arg: unknown): Promise<unknown>;
pageLimit: number;
}, Arg: string): Promise<unknown>;
getAllMemberList (groupCode: string, forceFetch: boolean): Promise<{
errCode: number,
@@ -114,12 +114,12 @@ export interface NodeIKernelGroupService {
result: {
ids: Array<{
uid: string,
index: number// 0
index: number;// 0
}>,
infos: Map<string, GroupMember>,
finish: true,
hasRobot: false
}
hasRobot: false;
};
}>;
setHeader (uid: string, path: string): Promise<GeneralCallResult>;
@@ -132,10 +132,10 @@ export interface NodeIKernelGroupService {
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,
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;
@@ -217,8 +217,8 @@ export interface NodeIKernelGroupService {
seq: string,
type: GroupNotifyMsgType,
groupCode: string,
postscript: string
}
postscript: string;
};
}): Promise<void>;
setTop (groupCode: string, isTop: boolean): void;
@@ -236,8 +236,8 @@ export interface NodeIKernelGroupService {
picInfo?: {
id: string,
width: number,
height: number
}
height: number;
};
}>;
downloadGroupBulletinRichMedia (groupCode: string): unknown;
@@ -249,12 +249,12 @@ export interface NodeIKernelGroupService {
getGroupRemainAtTimes (groupCode: string): Promise<Omit<GeneralCallResult, 'result'> & {
errCode: number,
atInfo: {
canAtAll: boolean
RemainAtAllCountForUin: number
RemainAtAllCountForGroup: number
atTimesMsg: string
canNotAtAllMsg: ''
}
canAtAll: boolean;
RemainAtAllCountForUin: number;
RemainAtAllCountForGroup: number;
atTimesMsg: string;
canNotAtAllMsg: '';
};
}>;
getJoinGroupNoVerifyFlag (groupCode: string): unknown;
@@ -267,30 +267,227 @@ export interface NodeIKernelGroupService {
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: {
groupCode: string,
srcId: number, // 73
needShortUrl: boolean, // true
additionalParam: string// ''
}): Promise<GeneralCallResult & { url?: string }>;
additionalParam: string;// ''
}): Promise<GeneralCallResult & { url?: string; }>;
modifyGroupExtInfo (groupCode: string, arg: unknown): void;
addGroupEssence (param: {
groupCode: string
groupCode: string;
msgRandom: number,
msgSeq: number
msgSeq: number;
}): Promise<unknown>;
removeGroupEssence (param: {
groupCode: string
groupCode: string;
msgRandom: number,
msgSeq: number
msgSeq: number;
}): Promise<unknown>;
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

@@ -29,10 +29,11 @@ export interface PasswordLoginArgType {
uin: string;
passwordMd5: string;// passwMD5
step: number;// 猜测是需要二次认证 参数 一次为0
newDeviceLoginSig: string;
proofWaterSig: string;
proofWaterRand: string;
proofWaterSid: string;
newDeviceLoginSig: Uint8Array;
proofWaterSig: Uint8Array;
proofWaterRand: Uint8Array;
proofWaterSid: Uint8Array;
unusualDeviceCheckSig: Uint8Array;
}
export interface LoginListItem {
@@ -63,7 +64,9 @@ export interface QuickLoginResult {
export interface NodeIKernelLoginService {
getMsfStatus: () => number;
setLoginMiscData (arg0: string, value: string): unknown;
setLoginMiscData (key: string, value: string): unknown;
getLoginMiscData (key: string): Promise<GeneralCallResult & { value: string; }>;
getMachineGuid (): string;
@@ -73,14 +76,12 @@ export interface NodeIKernelLoginService {
addKernelLoginListener (listener: NodeIKernelLoginListener): number;
removeKernelLoginListener (listener: number): void;
removeKernelLoginListener (listenerId: number): void;
initConfig (config: LoginInitConfig): void;
getLoginMiscData (data: string): Promise<GeneralCallResult & { value: string; }>;
getLoginList (): Promise<{
result: number, // 0是ok
result: number,
LocalLoginInfoList: LoginListItem[];
}>;
@@ -89,4 +90,32 @@ export interface NodeIKernelLoginService {
passwordLogin (param: PasswordLoginArgType): Promise<QuickLoginResult>;
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 {
getServerTime (): string;
getMsfStatus (): number;
online (): unknown;
offline (): unknown;
setNetworkProxy (param: {
userName: string,
userPwd: string,
@@ -50,4 +53,5 @@ export interface NodeIKernelMSFService {
accountType: number,
transInfoMap: Map<string, unknown>;
}): 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

@@ -3,25 +3,25 @@ export interface NodeIKernelMsgBackupService {
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 { 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 {
buildMultiForwardMsg (req: { srcMsgIds: Array<string>, srcContact: Peer; }): Promise<GeneralCallResult & { rspInfo: { elements: unknown; }; }>;
@@ -10,21 +10,21 @@ export interface NodeIKernelMsgService {
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>;
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;
getAutoReplyTextList (...args: unknown[]): unknown;
getAutoReplyTextList (): unknown;
getOnLineDev (): void;
@@ -52,85 +52,85 @@ export interface NodeIKernelMsgService {
downloadOnlineStatusCommonByUrl (arg0: string, arg1: string): unknown;
setToken (arg: unknown): unknown;
setToken (tokenInfo: TokenInfo): Promise<GeneralCallResult>;
switchForeGround (): unknown;
switchBackGround (arg: unknown): unknown;
switchBackGround (info: BackGroundInfo): Promise<GeneralCallResult>;
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>;
switchToOfflineSendMsg (peer: Peer, MsgId: string): unknown;
reqToOfflineSendMsg (...args: unknown[]): unknown;
reqToOfflineSendMsg (peer: Peer, msgId: string): unknown;
refuseReceiveOnlineFileMsg (peer: Peer, MsgId: string): unknown;
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 (...args: unknown[]): unknown;
addLocalTofuRecordMsg (peer: Peer, tofuRecord: TofuRecordElement): 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>;
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;
isMsgMatched (...args: unknown[]): unknown;
isMsgMatched (matchInfo: unknown): unknown;
getOnlineFileMsgs (peer: Peer): Promise<GeneralCallResult & {
msgList: {
@@ -147,7 +147,7 @@ export interface NodeIKernelMsgService {
}[]; // 一大坨,懒得写
}>;
getAllOnlineFileMsgs (...args: unknown[]): unknown;
getAllOnlineFileMsgs (): unknown;
getLatestDbMsgs (peer: Peer, cnt: number): Promise<GeneralCallResult & {
msgList: RawMessage[];
@@ -171,7 +171,7 @@ export interface NodeIKernelMsgService {
}>;
// @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: {
peer: Peer;
@@ -186,6 +186,7 @@ export interface NodeIKernelMsgService {
getMsgsBySeqRange (peer: Peer, startSeq: string, endSeq: string): Promise<GeneralCallResult & {
msgList: RawMessage[];
}>;
// @deprecated
getMsgsBySeqAndCount (peer: Peer, seq: string, count: number, desc: boolean, isReverseOrder: boolean): Promise<GeneralCallResult & {
msgList: RawMessage[];
@@ -211,19 +212,19 @@ export interface NodeIKernelMsgService {
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,
subtype: Array<number>;
}): 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,
subtype: Array<number>;
}>): 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>;
@@ -235,11 +236,11 @@ export interface NodeIKernelMsgService {
msgList: RawMessage[];
}>;
setMsgRichInfoFlag (...args: unknown[]): unknown;
setMsgRichInfoFlag (flag: boolean): void;
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>;
@@ -247,81 +248,81 @@ export interface NodeIKernelMsgService {
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>;
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;
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: {
md5HexStr: string,
@@ -334,15 +335,15 @@ export interface NodeIKernelMsgService {
file_uuid: '';
}): string;
assembleMobileQQRichMediaFilePath (...args: unknown[]): unknown;
assembleMobileQQRichMediaFilePath (arg: unknown): unknown;
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;
setPttPlayedState (...args: unknown[]): unknown;
setPttPlayedState (arg1: string, arg2: Peer, arg3: string): unknown;
fetchFavEmojiList (str: string, num: number, backward: boolean, forceRefresh: boolean): Promise<GeneralCallResult & {
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: {
latestMsgSeq: string,
@@ -419,17 +420,17 @@ export interface NodeIKernelMsgService {
peerContact: Peer;
}): 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: {
msgId: string,
@@ -440,7 +441,7 @@ export interface NodeIKernelMsgService {
downloadType: number,
}): Promise<any>;
cancelGetRichMediaElement (...args: unknown[]): unknown;
cancelGetRichMediaElement (arg: unknown): unknown;
refuseGetRichMediaElement (args: {
msgId: string,
@@ -451,7 +452,7 @@ export interface NodeIKernelMsgService {
downSourceType: number, // 1
}): Promise<void>;
switchToOfflineGetRichMediaElement (...args: unknown[]): unknown;
switchToOfflineGetRichMediaElement (arg: unknown): unknown;
downloadRichMedia (args: {
fileModelId: string,
@@ -473,21 +474,21 @@ export interface NodeIKernelMsgService {
guildId: string;
}): 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<{
result: number,
@@ -503,7 +504,7 @@ export interface NodeIKernelMsgService {
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: {
guildId?: string,
@@ -516,7 +517,7 @@ export interface NodeIKernelMsgService {
chatType: number; // 1私聊 2群
}): 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;
@@ -524,91 +525,91 @@ export interface NodeIKernelMsgService {
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>;
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;
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[];
}>;
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;
clearMsgRecords (...args: unknown[]): unknown;
clearMsgRecords (peer: Peer): unknown;
IsExistOldDb (...args: unknown[]): unknown;
IsExistOldDb (): unknown;
canImportOldDbMsg (...args: unknown[]): unknown;
canImportOldDbMsg (): 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;
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;
@@ -616,66 +617,66 @@ export interface NodeIKernelMsgService {
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>;// 频道的东西
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;
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>;// 表情推荐?
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;
setIKernelPublicAccountAdapter (...args: unknown[]): unknown;
setIKernelPublicAccountAdapter (arg: unknown): unknown;
// tempChatGameSession有关
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<{
extensionData: string;// "Hex"
@@ -696,38 +697,37 @@ export interface NodeIKernelMsgService {
msgType: number;
}): 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;// 猜的
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;
}

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;
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

@@ -8,9 +8,11 @@ export interface NodeIKernelOnlineStatusService {
setReadLikeList (arg: unknown): unknown;
getLikeList(arg: unknown): unknown;
getLikeList (arg: unknown): Promise<unknown>;
setLikeStatus(arg: unknown): unknown;
setLikeStatus (arg: unknown): Promise<unknown>;
setOnlineStatusLiteBusinessSwitch (enabled: boolean): void;
getAggregationPageEntrance (): unknown;
@@ -18,18 +20,9 @@ export interface NodeIKernelOnlineStatusService {
getAggregationGroupModels (): unknown;
// {
// "businessType": 1,
// "uins": [
// "1627126029",
// "66600000",
// "71702575"
// ]
// }
checkLikeStatus (param: {
businessType: number,
uins: string[]
uins: string[];
}): Promise<unknown>;
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

@@ -3,9 +3,9 @@ import { BuddyProfileLikeReq, GeneralCallResult, NTVoteInfo } from '@/napcat-cor
export interface NodeIKernelProfileLikeService {
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 & {
info: {
@@ -13,25 +13,25 @@ export interface NodeIKernelProfileLikeService {
uid: string,
time: string,
favoriteInfo: {
userInfos: Array<NTVoteInfo>, // 哪些人点我
userInfos: Array<NTVoteInfo>,
total_count: number,
last_time: number,
today_count: number
today_count: number;
},
voteInfo: {
total_count: number,
new_count: number,
new_nearby_count: number,
last_visit_time: number,
userInfos: Array<NTVoteInfo>, // 点过哪些人
}
userInfos: Array<NTVoteInfo>;
};
}>,
friendMaxVotes: number,
start: number
}
start: number;
};
}>;
getProfileLikeScidResourceInfo(...args: unknown[]): void;
getProfileLikeScidResourceInfo (arg: unknown): void;
isNull (): boolean;
}

View File

@@ -27,7 +27,7 @@ export interface NodeIKernelProfileService {
removeKernelProfileListener (listenerId: number): void;
prepareRegionConfig(...args: unknown[]): unknown;
prepareRegionConfig (): unknown;
getLocalStrangerRemark (): Promise<AnyCnameRecord>;
@@ -37,9 +37,9 @@ export interface NodeIKernelProfileService {
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>;
@@ -47,13 +47,13 @@ export interface NodeIKernelProfileService {
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>;
setRecommendImgFlag(...args: unknown[]): Promise<unknown>;
setRecommendImgFlag (flag: unknown): Promise<unknown>;
getUserSimpleInfo (force: boolean, uids: string[]): Promise<unknown>;
@@ -71,7 +71,7 @@ export interface NodeIKernelProfileService {
getSelfStatus (): Promise<unknown>;
setdisableEmojiShortCuts(...args: unknown[]): unknown;
setdisableEmojiShortCuts (arg: unknown): unknown;
getProfileQzonePicInfo (uid: string, type: number, force: boolean): Promise<unknown>;
@@ -79,4 +79,18 @@ export interface NodeIKernelProfileService {
getCoreInfo (sceneId: string, arg: unknown[]): unknown;
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,15 +4,17 @@ import { GeneralCallResult } from '@/napcat-core/services/common';
import { FSABRecentContactParams } from '@/napcat-core/types/contact';
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;
enterOrExitMsgList (arg: unknown): unknown;
getRecentContactListSnapShot (count: number): Promise<GeneralCallResult & {
info: {
@@ -28,40 +30,40 @@ export interface NodeIKernelRecentContactService {
peerUin: string,
msgTime: string,
chatType: ChatType,
msgId: string
}>
}
}>; // 1 arguments
msgId: string;
}>;
};
}>;
clearMsgUnreadCount(...args: unknown[]): unknown; // 1 arguments
clearMsgUnreadCount (peer: Peer): 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;
deleteRecentContacts(peer: Peer): unknown; // 猜测
deleteRecentContacts (peer: Peer): 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;
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>;

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

@@ -83,7 +83,7 @@ export interface NodeIKernelRichMediaService {
getVideoPlayUrlV2 (peer: Peer, msgId: string, elemId: string, videoCodecFormat: number, exParams: {
downSourceType: number,
triggerType: number
triggerType: number;
}): Promise<GeneralCallResult & {
urlResult: {
v4IpUrl: [],
@@ -91,10 +91,10 @@ export interface NodeIKernelRichMediaService {
domainUrl: Array<{
url: string,
isHttps: boolean,
httpsDomain: string
httpsDomain: string;
}>,
videoCodecFormat: number
}
videoCodecFormat: number;
};
}>;
getRichMediaFileDir (elementType: number, downType: number, isTemp: boolean): unknown;
@@ -111,13 +111,13 @@ export interface NodeIKernelRichMediaService {
peerUid: string,
guildId: string,
ele: MessageElement,
useHttps: boolean
useHttps: boolean;
}): Promise<unknown>;
isFileExpired (arg: number): unknown;
deleteGroupFolder (GroupCode: string, FolderId: string): Promise<GeneralCallResult & {
groupFileCommonResult: { retCode: number, retMsg: string, clientWording: string }
groupFileCommonResult: { retCode: number, retMsg: string, clientWording: string; };
}>;
// 参数与getVideoPlayUrlInVisit一样
@@ -133,7 +133,7 @@ export interface NodeIKernelRichMediaService {
peerUid: string,
guildId: string,
ele: MessageElement,
useHttps: boolean
useHttps: boolean;
}): unknown;
downloadFileForModelId (peer: Peer, ModelId: string[], unknown: string): Promise<unknown>;
@@ -150,7 +150,7 @@ export interface NodeIKernelRichMediaService {
fileId: string,
fileName: string,
fileSize: string,
fileModelId: string
fileModelId: string;
}[]): Promise<unknown>;
downloadFileByUrlList (fileDownloadTyp: UrlFileDownloadType, urlList: Array<string>): unknown;
@@ -158,22 +158,22 @@ export interface NodeIKernelRichMediaService {
downloadFileForFileInfo (fileInfo: CommonFileInfo[], savePath: string): unknown;
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;
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;
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;
@@ -183,43 +183,43 @@ export interface NodeIKernelRichMediaService {
getGroupFileList (groupCode: string, params: GetFileListParam): Promise<GeneralCallResult & {
groupSpaceResult: {
retCode: number
retMsg: string
clientWording: string
totalSpace: number
usedSpace: number
allUpload: boolean
}
retCode: number;
retMsg: string;
clientWording: string;
totalSpace: number;
usedSpace: number;
allUpload: boolean;
};
}>;
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 & {
moveGroupFileResult: {
result: {
retCode: number,
retMsg: symbol,
clientWording: string
clientWording: string;
},
successFileIdList: Array<string>,
failFileIdList: Array<string>
}
failFileIdList: Array<string>;
};
}>;
transGroupFile (groupCode: string, fileId: string): Promise<GeneralCallResult & {
transGroupFileResult: {
result: {
retCode: number
retMsg: string
clientWording: string
}
saveBusId: number
saveFilePath: string
}
retCode: number;
retMsg: string;
clientWording: string;
};
saveBusId: number;
saveFilePath: string;
};
}>;
searchGroupFile (
@@ -230,26 +230,26 @@ export interface NodeIKernelRichMediaService {
context: string,
count: number,
sortType: number,
groupNames: Array<string>
groupNames: Array<string>;
}): 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 & {
transGroupFileResult: {
result: unknown
successFileIdList: Array<unknown>
failFileIdList: Array<unknown>
}
result: unknown;
successFileIdList: Array<unknown>;
failFileIdList: Array<unknown>;
};
}>;
translateEnWordToZn(words: string[]): Promise<GeneralCallResult & { words: string[] }>;
translateEnWordToZn (words: string[]): Promise<GeneralCallResult & { words: string[]; }>;
getScreenOCR (path: string): Promise<unknown>;
batchGetGroupFileCount (Gids: Array<string>): Promise<GeneralCallResult & {
groupCodes: Array<string>,
groupFileCounts: Array<number>
groupFileCounts: Array<number>;
}>;
queryPicDownloadSize (arg: unknown): unknown;
@@ -258,15 +258,9 @@ export interface NodeIKernelRichMediaService {
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<{
fileId: string,
fileName: string,
fileSize: string,
fileModelId: string
}
>): unknown;
onlyDownloadFile (arg1: Peer, arg2: string, arg3: Array<unknown>[]): unknown;
onlyUploadFile (arg1: unknown, arg2: unknown): unknown;
@@ -276,9 +270,17 @@ export interface NodeIKernelRichMediaService {
bizType: RMBizTypeEnum,
filePath: string,
peerUid: string,
transferId: string
useNTV2: string
transferId: string;
useNTV2: string;
}): Promise<unknown>;
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,9 +2,11 @@ import { NodeIKernelRobotListener } from '@/napcat-core/listeners';
import { GeneralCallResult, Peer } from '..';
export interface NodeIKernelRobotService {
fetchGroupRobotStoreDiscovery(arg: unknown): unknown;
addKernelRobotListener (listener: NodeIKernelRobotListener): number;
sendGroupRobotStoreSearch(arg: unknown): unknown;
removeKernelRobotListener (listenerId: number): void;
fetchGroupRobotStoreDiscovery (arg: unknown): unknown;
fetchGroupRobotStoreCategoryList (arg: unknown): unknown;
@@ -18,31 +20,109 @@ export interface NodeIKernelRobotService {
fetchShareArkInfo (arg: unknown): unknown;
addKernelRobotListener(Listener: NodeIKernelRobotListener): number;
removeKernelRobotListener(ListenerId: number): unknown;
getAllRobotFriendsFromCache (): Promise<unknown>;
fetchAllRobots(arg1: unknown, arg2: unknown): unknown;
fetchAllRobots (arg1: boolean, arg2: unknown): unknown;
removeAllRecommendCache (): 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: {
uins: Array<string>,
num: 0,
client_info: { platform: 4, version: '', build_num: 9999 },
client_info: { platform: 4, version: '', build_num: 9999; },
tinyids: [],
page: 0,
full_fetch: false,
scene: 4,
filter: 1,
bkn: ''
}): Promise<GeneralCallResult & { response: { bot_features: Array<unknown>, next_page: number } }>;
bkn: '';
}): Promise<GeneralCallResult & { response: { bot_features: Array<unknown>, next_page: number; }; }>;
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

@@ -7,96 +7,104 @@ export interface NodeIKernelSearchService {
removeKernelSearchListener (listenerId: number): void;
searchStranger(unknown: string, searchStranger: unknown, searchParams: unknown): Promise<unknown>;
searchStranger (keyword: string, searchType: unknown, searchParams: unknown): Promise<unknown>;
searchGroup (param: {
keyWords: string,
groupNum: number,
exactSearch: boolean,
penetrate: string
}): Promise<GeneralCallResult>;// needs 1 arguments
penetrate: string;
}): 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;
searchChatAtMeMsgs (arg: unknown): unknown;
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, // 4
type: number,
contactList: [],
id: number, // -1
id: number,
groupInfos: [],
msgs: [],
fileInfos: [
{
fileInfos: Array<{
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: [],
groupChatInfo: Array<
{
groupChatInfo: Array<{
groupCode: string,
isConf: boolean,
hasModifyConfGroupFace: boolean,
hasModifyConfGroupName: boolean,
groupName: string,
remark: string
remark: string;
}>,
dataLineChatInfo: [],
tmpChatInfo: [],
@@ -108,29 +116,33 @@ export interface NodeIKernelSearchService {
senderRemark: string,
senderCard: string,
elemId: string,
elemType: string, // 3
elemType: string,
fileSize: string,
filePath: string,
fileName: string,
hits: Array<
{
start: 12,
end: 14
}
>
}
]
hits: Array<{ start: number, end: number; }>;
}>;
}): Promise<{
result: number,
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;
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>;
setSilentScan (is_silent: boolean): unknown;
setSilentScan (isSilent: boolean): 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

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

View File

@@ -4,19 +4,17 @@ export interface NodeIKernelTipOffService {
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 & {
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(args: unknown[]): Promise<unknown>;// 2
encodeUinAesInfo (arg1: unknown, arg2: unknown): Promise<unknown>;
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

@@ -4,14 +4,14 @@ export interface NodeIKernelUnitedConfigService {
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

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

View File

@@ -1,5 +1,11 @@
export interface NodeIYellowFaceService {
addListener (listener: unknown): number;
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 './NodeIKernelSearchService';
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 = {
NodeIKernelAvatarService: NodeIKernelAvatarService;
@@ -53,6 +83,6 @@ export type ServiceNamingMapping = {
NodeIKernelRichMediaService: NodeIKernelRichMediaService;
NodeIKernelDbToolsService: NodeIKernelDbToolsService;
NodeIKernelTipOffService: NodeIKernelTipOffService;
NodeIKernelSearchService: NodeIKernelSearchService,
NodeIKernelSearchService: NodeIKernelSearchService;
NodeIKernelCollectionService: NodeIKernelCollectionService;
};

View File

@@ -323,7 +323,7 @@ export interface FlashTransferInfo {
id: string;
urls: FlashTransferIcon[];
localCachePath: string;
}
};
}
/**
@@ -337,7 +337,7 @@ export interface MarkdownElement {
mdExtType?: number;
mdExtInfo?: {
flashTransferInfo: FlashTransferInfo;
}
};
}
/**
@@ -550,6 +550,96 @@ export interface QueryMsgsParams {
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接口
*/

View File

@@ -29,6 +29,28 @@ import { NodeIkernelTestPerformanceService } from './services/NodeIkernelTestPer
import { NodeIKernelECDHService } from './services/NodeIKernelECDHService';
import { NodeIO3MiscService } from './services/NodeIO3MiscService';
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 {
get (): NodeQQNTWrapperUtil;
@@ -39,46 +61,46 @@ export interface NodeQQNTWrapperUtil {
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;
startTrace (path: string): unknown; // 可能是错的
startTrace (path: string): unknown;
copyFile (src: string, dst: string): unknown;
genFileShaAndMd5Hex (path: string, unknown: number): unknown; // 可能是错的
genFileShaAndMd5Hex (path: string, unknown: number): unknown;
setTraceInfo (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;
matchInPinyin (arg0: unknown[], arg1: string): unknown; // 参数特复杂 arg0是个复杂数据类型
getPinyinExt (arg0: string, arg1: boolean): unknown;
matchInPinyin (arg0: unknown[], arg1: string): unknown;
makeDirByPath (arg0: string): unknown;
emptyWorkingSet (arg0: number): unknown; // 参数是UINT32
runProcess (arg0: string, arg1: boolean): unknown;
runProcessArgs (arg0: string, arg1: { [key: string]: string; }, arg2: boolean): unknown;
@@ -141,6 +163,24 @@ export interface NodeQQNTWrapperUtil {
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 (
serviceName: string,
filePath: string,
@@ -180,6 +220,43 @@ export interface NodeIQQNTWrapperSession {
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;
getECDHService (): NodeIKernelECDHService;
@@ -220,47 +297,47 @@ export interface NodeIQQNTWrapperSession {
getDirectSessionService (): unknown;
getRDeliveryService (): unknown;
getRDeliveryService (): NodeIKernelRDeliveryService;
getAvatarService (): NodeIKernelAvatarService;
getFeedChannelService (): unknown;
getYellowFaceService (): unknown;
getYellowFaceService (): NodeIYellowFaceService;
getCollectionService (): NodeIKernelCollectionService;
getSettingService (): unknown;
getSettingService (): NodeIKernelSettingService;
getQiDianService (): unknown;
getQiDianService (): NodeIKernelQiDianService;
getFileAssistantService (): unknown;
getFileAssistantService (): NodeIKernelFileAssistantService;
getGuildService (): unknown;
getSkinService (): unknown;
getSkinService (): NodeIKernelSkinService;
getTestPerformanceService (): NodeIkernelTestPerformanceService;
getQQPlayService (): unknown;
getQQPlayService (): NodeIKernelQQPlayService;
getDbToolsService (): unknown;
getDbToolsService (): NodeIKernelDbToolsService;
getUixConvertService (): NodeIKernelUixConvertService;
getOnlineStatusService (): unknown;
getOnlineStatusService (): NodeIKernelOnlineStatusService;
getRemotingService (): unknown;
getRemotingService (): NodeIKernelRemotingService;
getGroupTabService (): unknown;
getGroupTabService (): NodeIKernelGroupTabService;
getGroupSchoolService (): unknown;
getLiteBusinessService (): unknown;
getLiteBusinessService (): NodeIKernelLiteBusinessService;
getGuildMsgService (): unknown;
getLockService (): unknown;
getLockService (): NodeIKernelLockService;
getMSFService (): NodeIKernelMSFService;
@@ -270,7 +347,29 @@ export interface NodeIQQNTWrapperSession {
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 {
@@ -291,6 +390,14 @@ export interface NodeIQQNTWrapperEngine {
get (): NodeIQQNTWrapperEngine;
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 {

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,8 @@ import { NapCatPathWrapper } from 'napcat-common/src/path';
import { InitWebUi, WebUiConfig, webUiRuntimePort } from 'napcat-webui-backend/index';
import { NapCatAdapterManager } from 'napcat-adapter';
import { NativePacketHandler } from 'napcat-core/packet/handler/client';
import { Napi2NativeLoader } from 'napcat-core/packet/handler/napi2nativeLoader';
import { loadNapcatConfig } from '@/napcat-core/helper/config';
import { FFmpegService } from 'napcat-core/helper/ffmpeg/ffmpeg';
import { logSubscription, LogWrapper } from 'napcat-core/helper/log';
import { QQBasicInfoWrapper } from '@/napcat-core/helper/qq-basic-info';
@@ -40,10 +42,23 @@ export async function NCoreInitFramework (
const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
const wrapper = loadQQWrapper(basicInfoWrapper.QQMainPath, basicInfoWrapper.getFullQQVersion());
const nativePacketHandler = new NativePacketHandler({ logger }); // 初始化 NativePacketHandler 用于后续使用
const napi2nativeLoader = new Napi2NativeLoader({ logger }); // 初始化 Napi2NativeLoader 用于后续使用
const napcatConfig = loadNapcatConfig(pathWrapper.configPath);
//console.log('[NapCat] [Napi2NativeLoader]', napi2nativeLoader.nativeExports.enableAllBypasses?.());
if (process.env['NAPCAT_DISABLE_BYPASS'] !== '1') {
const bypassOptions = napcatConfig.bypass ?? {};
const bypassEnabled = napi2nativeLoader.nativeExports.enableAllBypasses?.(bypassOptions);
if (bypassEnabled) {
logger.log('[NapCat] Napi2NativeLoader: 已启用Bypass');
}
logger.log('[NapCat] Napi2NativeLoader: Framework模式Bypass配置:', bypassOptions);
} else {
logger.log('[NapCat] Napi2NativeLoader: Bypass已通过环境变量禁用');
}
// nativePacketHandler.onAll((packet) => {
// console.log('[Packet]', packet.uin, packet.cmd, packet.hex_data);
// });
await nativePacketHandler.init(basicInfoWrapper.getFullQQVersion());
await nativePacketHandler.init(basicInfoWrapper.getFullQQVersion(), napcatConfig.o3HookMode === 1 ? true : false);
// 在 init 之后注册监听器
// 初始化 FFmpeg 服务
@@ -73,11 +88,12 @@ export async function NCoreInitFramework (
// 过早进入会导致addKernelMsgListener等Listener添加失败
// await sleep(2500);
// 初始化 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();
// 启动WebUi
WebUiDataRuntime.setWorkingEnv(NapCatCoreWorkingEnv.Framework);
WebUiDataRuntime.setQQDataPath(loaderObject.core.dataPath);
InitWebUi(logger, pathWrapper, logSubscription, statusHelperSubscription).then().catch(e => logger.logError(e));
// 使用 NapCatAdapterManager 统一管理协议适配器
const adapterManager = new NapCatAdapterManager(loaderObject.core, loaderObject.context, pathWrapper);
@@ -100,10 +116,12 @@ export class NapCatFramework {
selfInfo: SelfInfo,
basicInfoWrapper: QQBasicInfoWrapper,
pathWrapper: NapCatPathWrapper,
packetHandler: NativePacketHandler
packetHandler: NativePacketHandler,
napi2nativeLoader: Napi2NativeLoader
) {
this.context = {
packetHandler,
napi2nativeLoader,
workingEnv: NapCatCoreWorkingEnv.Framework,
wrapper,
session,

View File

@@ -22,7 +22,8 @@
"napcat-adapter": "workspace:*",
"napcat-webui-backend": "workspace:*",
"napcat-vite": "workspace:*",
"napcat-qrcode": "workspace:*"
"napcat-qrcode": "workspace:*",
"json5": "^2.2.3"
},
"devDependencies": {
"@types/node": "^22.0.1"

Binary file not shown.

View File

@@ -13,14 +13,12 @@ import { URL } from 'url';
import { ActionName } from '@/napcat-onebot/action/router';
import { OB11HeartbeatEvent } from '@/napcat-onebot/event/meta/OB11HeartbeatEvent';
import { OB11LifeCycleEvent, LifeCycleSubType } from '@/napcat-onebot/event/meta/OB11LifeCycleEvent';
import { Mutex } from 'async-mutex';
export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig> {
private app: Express | undefined;
private server: http.Server | undefined;
private wsServer?: WebSocketServer;
private wsClients: WebSocket[] = [];
private wsClientsMutex = new Mutex();
private heartbeatIntervalId: NodeJS.Timeout | null = null;
private wsClientWithEvent: WebSocket[] = [];
@@ -30,7 +28,6 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
override async onEvent<T extends OB11EmitEventContent> (event: T) {
// http server is passive, no need to emit event
this.wsClientsMutex.runExclusive(async () => {
const promises = this.wsClientWithEvent.map((wsClient) => {
return new Promise<void>((resolve, reject) => {
if (wsClient.readyState === WebSocket.OPEN) {
@@ -42,7 +39,6 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
});
});
await Promise.allSettled(promises);
});
}
open () {
@@ -65,13 +61,9 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
this.server?.close();
this.app = undefined;
this.stopHeartbeat();
await this.wsClientsMutex.runExclusive(async () => {
this.wsClients.forEach((wsClient) => {
wsClient.close();
});
this.wsClients.forEach((wsClient) => wsClient.close());
this.wsClients = [];
this.wsClientWithEvent = [];
});
this.wsServer?.close();
}
@@ -153,14 +145,10 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
wsClient.on('message', (message) => {
this.handleWSMessage(wsClient, message).then().catch(e => this.logger.logError(e));
});
wsClient.on('ping', () => {
wsClient.pong();
});
wsClient.on('pong', () => {
// this.logger.logDebug('[OneBot] [HTTP WebSocket] Pong received');
});
wsClient.once('close', () => {
this.wsClientsMutex.runExclusive(async () => {
const NormolIndex = this.wsClients.indexOf(wsClient);
if (NormolIndex !== -1) {
this.wsClients.splice(NormolIndex, 1);
@@ -173,8 +161,6 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
this.stopHeartbeat();
}
});
});
await this.wsClientsMutex.runExclusive(async () => {
if (!isApiConnect) {
this.wsClientWithEvent.push(wsClient);
}
@@ -182,7 +168,6 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
if (this.wsClientWithEvent.length > 0) {
this.startHeartbeat();
}
});
}).on('error', (err) => this.logger.log('[OneBot] [HTTP WebSocket] Server Error:', err.message));
}
@@ -197,13 +182,11 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
private startHeartbeat () {
if (this.heartbeatIntervalId) return;
this.heartbeatIntervalId = setInterval(() => {
this.wsClientsMutex.runExclusive(async () => {
this.wsClientWithEvent.forEach((wsClient) => {
if (wsClient.readyState === WebSocket.OPEN) {
wsClient.send(JSON.stringify(new OB11HeartbeatEvent(this.core, 30000, this.core.selfInfo.online ?? true, true)));
}
});
});
}, 30000);
}

View File

@@ -196,9 +196,14 @@ export class OB11PluginMangerAdapter extends IOB11NetworkAdapter<PluginConfig> i
* 创建插件上下文
*/
private createPluginContext (entry: PluginEntry): NapCatPluginContext {
const dataPath = path.join(entry.pluginPath, 'data');
const dataPath = path.join(this.core.context.pathWrapper.configPath, 'plugins', entry.id);
const configPath = path.join(dataPath, 'config.json');
// 确保插件配置目录存在
if (!fs.existsSync(dataPath)) {
fs.mkdirSync(dataPath, { recursive: true });
}
// 创建插件专用日志器
const pluginPrefix = `[Plugin: ${entry.id}]`;
const coreLogger = this.logger;
@@ -358,7 +363,7 @@ export class OB11PluginMangerAdapter extends IOB11NetworkAdapter<PluginConfig> i
}
const pluginPath = entry.pluginPath;
const dataPath = path.join(pluginPath, 'data');
const dataPath = path.join(this.core.context.pathWrapper.configPath, 'plugins', pluginId);
if (entry.loaded) {
await this.unloadPlugin(entry);
@@ -372,7 +377,7 @@ export class OB11PluginMangerAdapter extends IOB11NetworkAdapter<PluginConfig> i
fs.rmSync(pluginPath, { recursive: true, force: true });
}
// 清理数据
// 清理插件配置数据
if (cleanData && fs.existsSync(dataPath)) {
fs.rmSync(dataPath, { recursive: true, force: true });
}
@@ -440,11 +445,7 @@ export class OB11PluginMangerAdapter extends IOB11NetworkAdapter<PluginConfig> i
* 获取插件数据目录路径
*/
public getPluginDataPath (pluginId: string): string {
const entry = this.plugins.get(pluginId);
if (!entry) {
throw new Error(`Plugin ${pluginId} not found`);
}
return path.join(entry.pluginPath, 'data');
return path.join(this.core.context.pathWrapper.configPath, 'plugins', pluginId);
}
/**

View File

@@ -173,9 +173,14 @@ export class OB11PluginManager extends IOB11NetworkAdapter<PluginConfig> impleme
* 创建插件上下文
*/
private createPluginContext (entry: PluginEntry): NapCatPluginContext {
const dataPath = path.join(entry.pluginPath, 'data');
const dataPath = path.join(this.core.context.pathWrapper.configPath, 'plugins', entry.id);
const configPath = path.join(dataPath, 'config.json');
// 确保插件配置目录存在
if (!fs.existsSync(dataPath)) {
fs.mkdirSync(dataPath, { recursive: true });
}
// 创建插件专用日志器
const pluginPrefix = `[Plugin: ${entry.id}]`;
const coreLogger = this.logger;
@@ -323,7 +328,7 @@ export class OB11PluginManager extends IOB11NetworkAdapter<PluginConfig> impleme
}
const pluginPath = entry.pluginPath;
const dataPath = path.join(pluginPath, 'data');
const dataPath = path.join(this.core.context.pathWrapper.configPath, 'plugins', pluginId);
// 先卸载插件
await this.unloadPlugin(entry);
@@ -336,7 +341,7 @@ export class OB11PluginManager extends IOB11NetworkAdapter<PluginConfig> impleme
fs.rmSync(pluginPath, { recursive: true, force: true });
}
// 清理数据
// 清理插件配置数据
if (cleanData && fs.existsSync(dataPath)) {
fs.rmSync(dataPath, { recursive: true, force: true });
}
@@ -404,11 +409,7 @@ export class OB11PluginManager extends IOB11NetworkAdapter<PluginConfig> impleme
* 获取插件数据目录路径
*/
public getPluginDataPath (pluginId: string): string {
const entry = this.plugins.get(pluginId);
if (!entry) {
throw new Error(`Plugin ${pluginId} not found`);
}
return path.join(entry.pluginPath, 'data');
return path.join(this.core.context.pathWrapper.configPath, 'plugins', pluginId);
}
/**

View File

@@ -15,6 +15,7 @@ export interface PluginPackageJson {
author?: string;
homepage?: string;
repository?: string | { type: string; url: string; };
icon?: string; // 插件图标文件路径(相对于插件目录),如 "icon.png"
}
// ==================== 插件配置 Schema ====================

View File

@@ -85,9 +85,6 @@ export class OB11WebSocketClientAdapter extends IOB11NetworkAdapter<WebsocketCli
},
});
this.connection.on('ping', () => {
this.connection?.pong();
});
this.connection.on('pong', () => {
// this.logger.logDebug('[OneBot] [WebSocket Client] 收到pong');
});

View File

@@ -1,7 +1,6 @@
import { OB11EmitEventContent, OB11NetworkReloadType } from './index';
import { URL } from 'url';
import { RawData, WebSocket, WebSocketServer } from 'ws';
import { Mutex } from 'async-mutex';
import { OB11Response } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { NapCatCore } from 'napcat-core';
@@ -17,7 +16,6 @@ import json5 from 'json5';
export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketServerConfig> {
wsServer?: WebSocketServer;
wsClients: WebSocket[] = [];
wsClientsMutex = new Mutex();
private heartbeatIntervalId: NodeJS.Timeout | null = null;
wsClientWithEvent: WebSocket[] = [];
@@ -58,14 +56,10 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
wsClient.on('message', (message) => {
this.handleMessage(wsClient, message).then().catch(e => this.logger.logError(e));
});
wsClient.on('ping', () => {
wsClient.pong();
});
wsClient.on('pong', () => {
// this.logger.logDebug('[OneBot] [WebSocket Server] Pong received');
});
wsClient.once('close', () => {
this.wsClientsMutex.runExclusive(async () => {
const NormolIndex = this.wsClients.indexOf(wsClient);
if (NormolIndex !== -1) {
this.wsClients.splice(NormolIndex, 1);
@@ -78,8 +72,6 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
this.stopHeartbeat();
}
});
});
await this.wsClientsMutex.runExclusive(async () => {
if (!isApiConnect) {
this.wsClientWithEvent.push(wsClient);
}
@@ -87,7 +79,6 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
if (this.wsClientWithEvent.length > 0) {
this.startHeartbeat();
}
});
}).on('error', (err) => this.logger.log('[OneBot] [WebSocket Server] Server Error:', err.message));
}
@@ -100,7 +91,6 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
}
async onEvent<T extends OB11EmitEventContent> (event: T) {
this.wsClientsMutex.runExclusive(async () => {
const promises = this.wsClientWithEvent.map((wsClient) => {
return new Promise<void>((resolve, reject) => {
if (wsClient.readyState === WebSocket.OPEN) {
@@ -112,7 +102,6 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
});
});
await Promise.allSettled(promises);
});
}
open () {
@@ -136,25 +125,19 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
}
});
this.stopHeartbeat();
await this.wsClientsMutex.runExclusive(async () => {
this.wsClients.forEach((wsClient) => {
wsClient.close();
});
this.wsClients.forEach((wsClient) => wsClient.close());
this.wsClients = [];
this.wsClientWithEvent = [];
});
}
private startHeartbeat () {
if (this.heartbeatIntervalId || this.config.heartInterval <= 0) return;
this.heartbeatIntervalId = setInterval(() => {
this.wsClientsMutex.runExclusive(async () => {
this.wsClientWithEvent.forEach((wsClient) => {
if (wsClient.readyState === WebSocket.OPEN) {
wsClient.send(JSON.stringify(new OB11HeartbeatEvent(this.core, this.config.heartInterval, this.core.selfInfo.online ?? true, true)));
}
});
});
}, this.config.heartInterval);
}

View File

@@ -26,7 +26,6 @@
"express": "^5.0.0",
"ws": "^8.18.3",
"file-type": "^21.0.0",
"async-mutex": "^0.5.0",
"napcat-protobuf": "workspace:*",
"json5": "^2.2.3",
"napcat-core": "workspace:*",

View File

@@ -20,6 +20,7 @@ import { hostname, systemVersion } from 'napcat-common/src/system';
import path from 'path';
import fs from 'fs';
import os from 'os';
import { createHash } from 'node:crypto';
import { LoginListItem, NodeIKernelLoginService } from 'napcat-core/services';
import qrcode from 'napcat-qrcode/lib/main';
import { NapCatAdapterManager } from 'napcat-adapter';
@@ -30,12 +31,15 @@ import { NodeIO3MiscListener } from 'napcat-core/listeners/NodeIO3MiscListener';
import { sleep } from 'napcat-common/src/helper';
import { FFmpegService } from '@/napcat-core/helper/ffmpeg/ffmpeg';
import { NativePacketHandler } from 'napcat-core/packet/handler/client';
import { Napi2NativeLoader } from 'napcat-core/packet/handler/napi2nativeLoader';
import { loadNapcatConfig } from '@/napcat-core/helper/config';
import { logSubscription, LogWrapper } from '@/napcat-core/helper/log';
import { proxiedListenerOf } from '@/napcat-core/helper/proxy-handler';
import { QQBasicInfoWrapper } from '@/napcat-core/helper/qq-basic-info';
import { statusHelperSubscription } from '@/napcat-core/helper/status';
import { applyPendingUpdates } from '@/napcat-webui-backend/src/api/UpdateNapCat';
import { connectToNamedPipe } from './pipe';
// NapCat Shell App ES 入口文件
async function handleUncaughtExceptions (logger: LogWrapper) {
process.on('uncaughtException', (err) => {
@@ -191,6 +195,24 @@ async function handleLogin (
return await selfInfo;
}
async function handleLoginInner (context: { isLogined: boolean; }, logger: LogWrapper, loginService: NodeIKernelLoginService, quickLoginUin: string | undefined, historyLoginList: LoginListItem[]) {
const resolveQuickPasswordMd5 = (): string | undefined => {
const quickPasswordMd5 = process.env['NAPCAT_QUICK_PASSWORD_MD5']?.trim();
if (quickPasswordMd5) {
if (/^[a-fA-F0-9]{32}$/.test(quickPasswordMd5)) {
return quickPasswordMd5.toLowerCase();
}
logger.logError('NAPCAT_QUICK_PASSWORD_MD5 格式无效(需为 32 位 MD5');
}
const quickPassword = process.env['NAPCAT_QUICK_PASSWORD'];
if (typeof quickPassword === 'string' && quickPassword.length > 0) {
logger.log('检测到 NAPCAT_QUICK_PASSWORD已在内存中计算 MD5 用于回退登录');
return createHash('md5').update(quickPassword, 'utf8').digest('hex');
}
return undefined;
};
// 注册刷新二维码回调
WebUiDataRuntime.setRefreshQRCodeCallback(async () => {
loginService.getQRCodePicture();
@@ -201,10 +223,12 @@ async function handleLoginInner (context: { isLogined: boolean; }, logger: LogWr
if (uin) {
logger.log('正在快速登录 ', uin);
loginService.quickLoginWithUin(uin).then(res => {
if (res.loginErrorInfo.errMsg) {
WebUiDataRuntime.setQQLoginError(res.loginErrorInfo.errMsg);
const quickLoginSuccess = res.result === '0' && !res.loginErrorInfo?.errMsg;
if (!quickLoginSuccess) {
const errMsg = res.loginErrorInfo?.errMsg || `快速登录失败,错误码: ${res.result}`;
WebUiDataRuntime.setQQLoginError(errMsg);
loginService.getQRCodePicture();
resolve({ result: false, message: res.loginErrorInfo.errMsg });
resolve({ result: false, message: errMsg });
} else {
WebUiDataRuntime.setQQLoginStatus(true);
WebUiDataRuntime.setQQLoginError('');
@@ -231,21 +255,43 @@ async function handleLoginInner (context: { isLogined: boolean; }, logger: LogWr
uin,
passwordMd5,
step: 0,
newDeviceLoginSig: '',
proofWaterSig: '',
proofWaterRand: '',
proofWaterSid: '',
newDeviceLoginSig: new Uint8Array(),
proofWaterSig: new Uint8Array(),
proofWaterRand: new Uint8Array(),
proofWaterSid: new Uint8Array(),
unusualDeviceCheckSig: new Uint8Array(),
}).then(res => {
if (res.result === '140022008') {
const errMsg = '需要验证码,暂不支持';
WebUiDataRuntime.setQQLoginError(errMsg);
loginService.getQRCodePicture();
resolve({ result: false, message: errMsg });
const proofWaterUrl = res.loginErrorInfo?.proofWaterUrl || '';
logger.log('需要验证码, proofWaterUrl: ', proofWaterUrl);
resolve({
result: false,
message: '需要验证码',
needCaptcha: true,
proofWaterUrl,
});
} else if (res.result === '140022010') {
const errMsg = '新设备需要扫码登录,暂不支持';
WebUiDataRuntime.setQQLoginError(errMsg);
loginService.getQRCodePicture();
resolve({ result: false, message: errMsg });
const jumpUrl = res.loginErrorInfo?.jumpUrl || '';
const newDevicePullQrCodeSig = res.loginErrorInfo?.newDevicePullQrCodeSig || '';
logger.log('新设备需要扫码验证, jumpUrl: ', jumpUrl);
resolve({
result: false,
message: '新设备需要扫码验证',
needNewDevice: true,
jumpUrl,
newDevicePullQrCodeSig,
});
} else if (res.result === '140022011') {
const jumpUrl = res.loginErrorInfo?.jumpUrl || '';
const newDevicePullQrCodeSig = res.loginErrorInfo?.newDevicePullQrCodeSig || '';
logger.log('异常设备需要验证, jumpUrl: ', jumpUrl);
resolve({
result: false,
message: '异常设备需要验证',
needNewDevice: true,
jumpUrl,
newDevicePullQrCodeSig,
});
} else if (res.result !== '0') {
const errMsg = res.loginErrorInfo?.errMsg || '密码登录失败';
WebUiDataRuntime.setQQLoginError(errMsg);
@@ -267,21 +313,170 @@ async function handleLoginInner (context: { isLogined: boolean; }, logger: LogWr
}
});
});
const tryPasswordFallbackLogin = async (uin: string): Promise<{ success: boolean, attempted: boolean; }> => {
const quickPasswordMd5 = resolveQuickPasswordMd5();
if (!quickPasswordMd5) {
logger.log(`QQ ${uin} 未配置回退密码环境变量,建议优先使用 ACCOUNT + NAPCAT_QUICK_PASSWORDNAPCAT_QUICK_PASSWORD_MD5 作为备用),将使用二维码登录方式`);
return { success: false, attempted: false };
}
logger.log('正在尝试密码回退登录 ', uin);
const fallbackResult = await WebUiDataRuntime.requestPasswordLogin(uin, quickPasswordMd5);
if (fallbackResult.result) {
logger.log('密码回退登录成功 ', uin);
return { success: true, attempted: true };
}
if (fallbackResult.needCaptcha) {
const captchaTip = fallbackResult.proofWaterUrl
? `密码回退需要验证码,请在 WebUi 中继续完成验证:${fallbackResult.proofWaterUrl}`
: '密码回退需要验证码,请在 WebUi 中继续完成验证';
logger.logWarn(captchaTip);
WebUiDataRuntime.setQQLoginError('密码回退需要验证码,请在 WebUi 中继续完成验证');
return { success: false, attempted: true };
}
if (fallbackResult.needNewDevice) {
const newDeviceTip = fallbackResult.jumpUrl
? `密码回退需要新设备验证,请在 WebUi 中继续完成验证:${fallbackResult.jumpUrl}`
: '密码回退需要新设备验证,请在 WebUi 中继续完成验证';
logger.logWarn(newDeviceTip);
WebUiDataRuntime.setQQLoginError('密码回退需要新设备验证,请在 WebUi 中继续完成验证');
return { success: false, attempted: true };
}
logger.logError('密码回退登录失败:', fallbackResult.message);
return { success: false, attempted: true };
};
// 注册验证码登录回调(密码登录需要验证码时的第二步)
WebUiDataRuntime.setCaptchaLoginCall(async (uin: string, passwordMd5: string, ticket: string, randstr: string, sid: string) => {
return await new Promise((resolve) => {
if (uin && passwordMd5 && ticket) {
logger.log('正在验证码登录 ', uin);
loginService.passwordLogin({
uin,
passwordMd5,
step: 1,
newDeviceLoginSig: new Uint8Array(),
proofWaterSig: new TextEncoder().encode(ticket),
proofWaterRand: new TextEncoder().encode(randstr),
proofWaterSid: new TextEncoder().encode(sid),
unusualDeviceCheckSig: new Uint8Array(),
}).then(res => {
console.log('验证码登录结果: ', res);
if (res.result === '140022010') {
const jumpUrl = res.loginErrorInfo?.jumpUrl || '';
const newDevicePullQrCodeSig = res.loginErrorInfo?.newDevicePullQrCodeSig || '';
logger.log('验证码登录后需要新设备验证, jumpUrl: ', jumpUrl);
resolve({
result: false,
message: '新设备需要扫码验证',
needNewDevice: true,
jumpUrl,
newDevicePullQrCodeSig,
});
} else if (res.result === '140022011') {
const jumpUrl = res.loginErrorInfo?.jumpUrl || '';
const newDevicePullQrCodeSig = res.loginErrorInfo?.newDevicePullQrCodeSig || '';
logger.log('验证码登录后需要异常设备验证, jumpUrl: ', jumpUrl);
resolve({
result: false,
message: '异常设备需要验证',
needNewDevice: true,
jumpUrl,
newDevicePullQrCodeSig,
});
} else if (res.result !== '0') {
const errMsg = res.loginErrorInfo?.errMsg || '验证码登录失败';
WebUiDataRuntime.setQQLoginError(errMsg);
loginService.getQRCodePicture();
resolve({ result: false, message: errMsg });
} else {
WebUiDataRuntime.setQQLoginStatus(true);
WebUiDataRuntime.setQQLoginError('');
resolve({ result: true, message: '' });
}
}).catch((e) => {
logger.logError(e);
WebUiDataRuntime.setQQLoginError('验证码登录发生错误');
loginService.getQRCodePicture();
resolve({ result: false, message: '验证码登录发生错误' });
});
} else {
resolve({ result: false, message: '验证码登录失败:参数不完整' });
}
});
});
// 注册新设备登录回调(密码登录需要新设备验证时的第二步)
WebUiDataRuntime.setNewDeviceLoginCall(async (uin: string, passwordMd5: string, newDevicePullQrCodeSig: string) => {
return await new Promise((resolve) => {
if (uin && passwordMd5 && newDevicePullQrCodeSig) {
logger.log('正在新设备验证登录 ', uin);
loginService.passwordLogin({
uin,
passwordMd5,
step: 2,
newDeviceLoginSig: new TextEncoder().encode(newDevicePullQrCodeSig),
proofWaterSig: new Uint8Array(),
proofWaterRand: new Uint8Array(),
proofWaterSid: new Uint8Array(),
unusualDeviceCheckSig: new Uint8Array(),
}).then(res => {
if (res.result === '140022011') {
const jumpUrl = res.loginErrorInfo?.jumpUrl || '';
const newDevicePullQrCodeSig = res.loginErrorInfo?.newDevicePullQrCodeSig || '';
logger.log('新设备验证后需要异常设备验证, jumpUrl: ', jumpUrl);
resolve({
result: false,
message: '异常设备需要验证',
needNewDevice: true,
jumpUrl,
newDevicePullQrCodeSig,
});
} else if (res.result !== '0') {
const errMsg = res.loginErrorInfo?.errMsg || '新设备验证登录失败';
WebUiDataRuntime.setQQLoginError(errMsg);
loginService.getQRCodePicture();
resolve({ result: false, message: errMsg });
} else {
WebUiDataRuntime.setQQLoginStatus(true);
WebUiDataRuntime.setQQLoginError('');
resolve({ result: true, message: '' });
}
}).catch((e) => {
logger.logError(e);
WebUiDataRuntime.setQQLoginError('新设备验证登录发生错误');
loginService.getQRCodePicture();
resolve({ result: false, message: '新设备验证登录发生错误' });
});
} else {
resolve({ result: false, message: '新设备验证登录失败:参数不完整' });
}
});
});
if (quickLoginUin) {
if (historyLoginList.some(u => u.uin === quickLoginUin)) {
logger.log('正在快速登录 ', quickLoginUin);
loginService.quickLoginWithUin(quickLoginUin)
.then(result => {
if (result.loginErrorInfo.errMsg) {
logger.logError('快速登录错误:', result.loginErrorInfo.errMsg);
WebUiDataRuntime.setQQLoginError(result.loginErrorInfo.errMsg);
if (!context.isLogined) loginService.getQRCodePicture();
.then(async result => {
const quickLoginSuccess = result.result === '0' && !result.loginErrorInfo?.errMsg;
if (!quickLoginSuccess) {
const errMsg = result.loginErrorInfo?.errMsg || `快速登录失败,错误码: ${result.result}`;
logger.logError('快速登录错误:', errMsg);
WebUiDataRuntime.setQQLoginError(errMsg);
const { success, attempted } = await tryPasswordFallbackLogin(quickLoginUin);
if (!success && !attempted && !context.isLogined) loginService.getQRCodePicture();
}
})
.catch();
.catch(async (error) => {
logger.logError('快速登录异常:', error);
WebUiDataRuntime.setQQLoginError('快速登录发生错误');
const { success, attempted } = await tryPasswordFallbackLogin(quickLoginUin);
if (!success && !attempted && !context.isLogined) loginService.getQRCodePicture();
});
} else {
logger.logError('快速登录失败,未找到该 QQ 历史登录记录,将使用二维码登录方式');
if (!context.isLogined) loginService.getQRCodePicture();
logger.logError('快速登录失败,未找到该 QQ 历史登录记录,将尝试密码回退登录');
const { success, attempted } = await tryPasswordFallbackLogin(quickLoginUin);
if (!success && !attempted && !context.isLogined) loginService.getQRCodePicture();
}
} else {
logger.log('没有 -q 指令指定快速登录,将使用二维码登录方式');
@@ -387,20 +582,31 @@ export async function NCoreInitShell () {
handleUncaughtExceptions(logger);
await applyPendingUpdates(pathWrapper, logger);
// 提前初始化 Native 模块(在登录前加载)
const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
const nativePacketHandler = new NativePacketHandler({ logger });
const napi2nativeLoader = new Napi2NativeLoader({ logger });
// 初始化 FFmpeg 服务
await FFmpegService.init(pathWrapper.binaryPath, logger);
if (!(process.env['NAPCAT_DISABLE_PIPE'] === '1' || process.env['NAPCAT_WORKER_PROCESS'] === '1')) {
await connectToNamedPipe(logger).catch(e => logger.logError('命名管道连接失败', e));
}
const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
const wrapper = loadQQWrapper(basicInfoWrapper.QQMainPath, basicInfoWrapper.getFullQQVersion());
const nativePacketHandler = new NativePacketHandler({ logger }); // 初始化 NativePacketHandler 用于后续使用
// nativePacketHandler.onAll((packet) => {
// console.log('[Packet]', packet.uin, packet.cmd, packet.hex_data);
// });
await nativePacketHandler.init(basicInfoWrapper.getFullQQVersion());
// wrapper.node 加载后再初始化 hook按 schema 读取配置
const napcatConfig = loadNapcatConfig(pathWrapper.configPath);
await nativePacketHandler.init(basicInfoWrapper.getFullQQVersion(), napcatConfig.o3HookMode === 1 ? true : false);
if (process.env['NAPCAT_ENABLE_VERBOSE_LOG'] === '1') {
napi2nativeLoader.nativeExports.setVerbose?.(true);
}
// wrapper.node 加载后立刻启用 Bypass可通过环境变量禁用
if (process.env['NAPCAT_DISABLE_BYPASS'] !== '1') {
const bypassOptions = napcatConfig.bypass ?? {};
napi2nativeLoader.nativeExports.enableAllBypasses?.(bypassOptions);
} else {
logger.log('[NapCat] Napi2NativeLoader: Bypass已通过环境变量禁用');
}
const o3Service = wrapper.NodeIO3MiscService.get();
o3Service.addO3MiscListener(new NodeIO3MiscListener());
@@ -425,6 +631,7 @@ export async function NCoreInitShell () {
}
}
const [dataPath, dataPathGlobal] = getDataPaths(wrapper);
WebUiDataRuntime.setQQDataPath(dataPath);
const systemPlatform = getPlatformType();
if (!basicInfoWrapper.QQVersionAppid || !basicInfoWrapper.QQVersionQua) throw new Error('QQVersionAppid or QQVersionQua is not defined');
@@ -450,6 +657,13 @@ export async function NCoreInitShell () {
o3Service.reportAmgomWeather('login', 'a1', [dataTimestape, '0', '0']);
const selfInfo = await handleLogin(loginService, logger, pathWrapper, quickLoginUin, historyLoginList);
// 登录成功后通知 Master 进程(用于切换崩溃重试策略)
if (typeof process.send === 'function') {
process.send({ type: 'login-success' });
logger.log('[NapCat] 已通知主进程登录成功');
}
const amgomDataPiece = 'eb1fd6ac257461580dc7438eb099f23aae04ca679f4d88f53072dc56e3bb1129';
o3Service.setAmgomDataPiece(basicInfoWrapper.QQVersionAppid, new Uint8Array(Buffer.from(amgomDataPiece, 'hex')));
@@ -487,7 +701,8 @@ export async function NCoreInitShell () {
selfInfo,
basicInfoWrapper,
pathWrapper,
nativePacketHandler
nativePacketHandler,
napi2nativeLoader
).InitNapCat();
}
@@ -502,10 +717,12 @@ export class NapCatShell {
selfInfo: SelfInfo,
basicInfoWrapper: QQBasicInfoWrapper,
pathWrapper: NapCatPathWrapper,
packetHandler: NativePacketHandler
packetHandler: NativePacketHandler,
napi2nativeLoader: Napi2NativeLoader
) {
this.context = {
packetHandler,
napi2nativeLoader,
workingEnv: NapCatCoreWorkingEnv.Shell,
wrapper,
session,

View File

@@ -45,7 +45,7 @@ const ENV = {
// Worker 消息类型
interface WorkerMessage {
type: 'restart' | 'restart-prepare' | 'shutdown';
type: 'restart' | 'restart-prepare' | 'shutdown' | 'login-success';
secretKey?: string;
port?: number;
}
@@ -65,6 +65,7 @@ const recentCrashTimestamps: number[] = [];
const CRASH_TIME_WINDOW = 10000; // 10秒时间窗口
const MAX_CRASHES_IN_WINDOW = 3; // 最大崩溃次数
/**
* 获取进程类型名称(用于日志)
*/
@@ -113,6 +114,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 进程
*/
@@ -166,6 +203,13 @@ export async function restartWorker (secretKey?: string, port?: number): Promise
// 5. 启动新进程(重启模式不传递快速登录参数,传递密钥和端口)
await startWorker(false, secretKey, port);
// 6. Electron 模式下清理可能残留的子进程
if (isElectron && currentWorker?.pid) {
const excludePids = [process.pid, currentWorker.pid];
await cleanupOrphanedProcesses(excludePids);
}
isRestarting = false;
}
@@ -232,6 +276,8 @@ async function startWorker (passQuickLogin: boolean = true, secretKey?: string,
restartWorker(message.secretKey, message.port).catch(e => {
logger.logError(`[NapCat] [${processType}] 重启Worker进程失败:`, e);
});
} else if (message.type === 'login-success') {
logger.log(`[NapCat] [${processType}] Worker进程已登录成功切换到正常重试策略`);
}
}
});
@@ -254,13 +300,13 @@ async function startWorker (passQuickLogin: boolean = true, secretKey?: string,
// 记录本次崩溃
recentCrashTimestamps.push(now);
// 检查是否超过崩溃阈值
if (recentCrashTimestamps.length >= MAX_CRASHES_IN_WINDOW) {
logger.logError(`[NapCat] [${processType}] Worker进程在 ${CRASH_TIME_WINDOW / 1000} 秒内异常退出 ${MAX_CRASHES_IN_WINDOW} 次,主进程退出`);
process.exit(1);
}
logger.logWarn(`[NapCat] [${processType}] Worker进程意外退出 (${recentCrashTimestamps.length}/${MAX_CRASHES_IN_WINDOW}),正在尝试重新拉起...`);
startWorker(true).catch(e => {
logger.logError(`[NapCat] [${processType}] 重新拉起Worker进程失败:`, e);
});

View File

@@ -25,6 +25,7 @@
"napcat-qrcode": "workspace:*"
},
"devDependencies": {
"json5": "^2.2.3",
"@types/node": "^22.0.1",
"napcat-vite": "workspace:*"
},

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