Compare commits

...

15 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
8e8b874419 Improve: Use explicit conversion and keep descriptive names for 'all'
- Use explicit conditional for user_id conversion instead of || operator
- Keep '全体成员' for nickname/card so clients can display meaningful text

Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-11-07 10:49:24 +00:00
copilot-swe-agent[bot]
af4865e043 Fix: Skip UID conversion for user_id='all' in GetGroupMemberInfo
When user_id='all' or '0', return minimal member data without attempting UID conversion. This allows @all mentions to be processed normally without throwing Uin2Uid errors.

Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-11-07 10:45:45 +00:00
copilot-swe-agent[bot]
b6117ed205 Fix: Return mock data for user_id='all' in GetGroupMemberInfo
Instead of throwing an error, return a special mock member object representing "all members" when user_id='all'. This allows @all mentions to be processed normally without errors.

Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-11-07 10:33:35 +00:00
copilot-swe-agent[bot]
76bf3719f1 Fix: Update comment to Chinese for consistency
Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-11-07 10:21:32 +00:00
copilot-swe-agent[bot]
f3b9f1916f Fix: Add validation for user_id='all' in group member actions
Add early validation to reject user_id='all' with clear error messages in:
- GetGroupMemberInfo
- SetGroupKick
- SetGroupAdmin
- SetGroupBan
- SetGroupCard

This prevents "Uin2Uid Error: 用户ID all 不存在" when receiving @all mentions.

Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-11-07 10:19:06 +00:00
copilot-swe-agent[bot]
8e8fc471ed Initial exploration - understanding the bug
Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-11-07 10:15:13 +00:00
copilot-swe-agent[bot]
21de6660db Initial plan 2025-11-07 10:10:04 +00:00
Mlikiowa
202338a160 release: v4.9.27 2025-11-07 09:05:14 +00:00
手瓜一十雪
e3eb129a52 Update ffmpeg native binaries for all platforms
Replaces ffmpegAddon binaries for Darwin ARM64, Linux ARM64, Linux x64, and Windows x64 with new versions. Ensures compatibility and includes latest native changes.
2025-11-07 17:04:29 +08:00
手瓜一十雪
7654e9f2bb Update ffmpeg native binaries for all platforms
Replaces ffmpegAddon binaries for Darwin ARM64, Linux ARM64, Linux x64, and Windows x64. Ensures compatibility and includes latest native code updates.
2025-11-07 12:54:36 +08:00
Mlikiowa
a60c03f42f release: v4.9.26 2025-11-06 15:15:20 +00:00
手瓜一十雪
60aae228a1 feat: add Node NapCat Test 2025-11-06 17:57:57 +08:00
手瓜一十雪
b1417f9b56 feat: support node test 2025-11-06 10:57:54 +08:00
手瓜一十雪
eeeaddbb60 Remove development guide from README
Deleted the section detailing code checks and TypeScript error notes prior to code submission. This streamlines the README and removes internal development instructions.
2025-11-05 12:24:21 +08:00
Mlikiowa
b1109022bb release: v4.9.25 2025-11-04 13:55:32 +00:00
18 changed files with 174 additions and 303 deletions

1
.gitignore vendored
View File

@@ -14,3 +14,4 @@ devconfig/*
*.db
checkVersion.sh
bun.lockb
tests/run/

View File

@@ -45,37 +45,6 @@ _Modern protocol-side framework implemented based on NTQQ._
> 项目非盈利,对接问题/基础问题/下层框架问题 请自行搜索解决,本项目社区不提供此类解答。
## Development Guide
### 代码提交前检查
在提交代码前,**必须**执行以下命令进行代码检查:
```bash
# 1. 代码格式化修复
npm run lint:fix
# 2. TypeScript 类型检查
npm run tsc
```
#### 关于 TypeScript 类型检查
执行 `npm run tsc` 时,会出现 22 个已知的第三方库类型错误,**这是正常现象**
```
Found 22 errors in 3 files.
Errors Files
3 node_modules/@homebridge/node-pty-prebuilt-multiarch/src/eventEmitter2.ts:42
2 node_modules/@homebridge/node-pty-prebuilt-multiarch/src/terminal.ts:158
17 node_modules/@napneko/nap-proto-core/NapProto.ts:94
```
这些错误是由于启用了严格类型检查模式导致的第三方库内部类型问题,**不影响项目运行**。
⚠️ **注意**:除了上述 22 个已知错误外,不应该出现其他类型错误。如果有新的错误,请在提交前修复。
## Link
| 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/) |

View File

@@ -4,7 +4,7 @@
"name": "NapCatQQ",
"slug": "NapCat.Framework",
"description": "高性能的 OneBot 11 协议实现",
"version": "4.9.24",
"version": "4.9.27",
"icon": "./logo.png",
"authors": [
{

View File

@@ -84,7 +84,6 @@
"zod": "^3.24.1"
},
"devDependencies": {
"@eslint/js": "^9.19.0",
"@react-types/shared": "^3.26.0",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"@types/crypto-js": "^4.2.2",
@@ -95,20 +94,14 @@
"@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3",
"@types/react-window": "^1.8.8",
"@typescript-eslint/eslint-plugin": "^8.22.0",
"@typescript-eslint/parser": "^8.22.0",
"@vitejs/plugin-react": "^4.3.4",
"autoprefixer": "^10.4.20",
"eslint": "^9.19.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "5.2.3",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-unused-imports": "^4.1.4",
"globals": "^15.14.0",
"postcss": "^8.5.1",
"prettier": "^3.4.2",
"typescript": "^5.7.3",
@@ -8190,6 +8183,8 @@
"integrity": "sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.34.0",
@@ -8220,6 +8215,8 @@
"integrity": "sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.34.0",
"@typescript-eslint/types": "8.34.0",
@@ -8245,6 +8242,8 @@
"integrity": "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.34.0",
"@typescript-eslint/types": "^8.34.0",
@@ -8267,6 +8266,8 @@
"integrity": "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@typescript-eslint/types": "8.34.0",
"@typescript-eslint/visitor-keys": "8.34.0"
@@ -8285,6 +8286,8 @@
"integrity": "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
@@ -8302,6 +8305,8 @@
"integrity": "sha512-n7zSmOcUVhcRYC75W2pnPpbO1iwhJY3NLoHEtbJwJSNlVAZuwqu05zY3f3s2SDWWDSo9FdN5szqc73DCtDObAg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "8.34.0",
"@typescript-eslint/utils": "8.34.0",
@@ -8326,6 +8331,8 @@
"integrity": "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
@@ -8340,6 +8347,8 @@
"integrity": "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@typescript-eslint/project-service": "8.34.0",
"@typescript-eslint/tsconfig-utils": "8.34.0",
@@ -8369,6 +8378,8 @@
"integrity": "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.34.0",
@@ -8393,6 +8404,8 @@
"integrity": "sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@typescript-eslint/types": "8.34.0",
"eslint-visitor-keys": "^4.2.0"
@@ -8411,6 +8424,8 @@
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"optional": true,
"peer": true,
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
@@ -8663,27 +8678,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array.prototype.findlast": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
"integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.2",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"es-shim-unscopables": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array.prototype.findlastindex": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz",
@@ -8744,23 +8738,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array.prototype.tosorted": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
"integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.3",
"es-errors": "^1.3.0",
"es-shim-unscopables": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/arraybuffer.prototype.slice": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
@@ -9681,34 +9658,6 @@
"node": ">= 0.4"
}
},
"node_modules/es-iterator-helpers": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz",
"integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.3",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.6",
"es-errors": "^1.3.0",
"es-set-tostringtag": "^2.0.3",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.6",
"globalthis": "^1.0.4",
"gopd": "^1.2.0",
"has-property-descriptors": "^1.0.2",
"has-proto": "^1.2.0",
"has-symbols": "^1.1.0",
"internal-slot": "^1.1.0",
"iterator.prototype": "^1.1.4",
"safe-array-concat": "^1.1.3"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
@@ -9898,6 +9847,8 @@
"integrity": "sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
@@ -10206,104 +10157,6 @@
}
}
},
"node_modules/eslint-plugin-react": {
"version": "7.37.5",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
"integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
"dev": true,
"license": "MIT",
"dependencies": {
"array-includes": "^3.1.8",
"array.prototype.findlast": "^1.2.5",
"array.prototype.flatmap": "^1.3.3",
"array.prototype.tosorted": "^1.1.4",
"doctrine": "^2.1.0",
"es-iterator-helpers": "^1.2.1",
"estraverse": "^5.3.0",
"hasown": "^2.0.2",
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
"minimatch": "^3.1.2",
"object.entries": "^1.1.9",
"object.fromentries": "^2.0.8",
"object.values": "^1.2.1",
"prop-types": "^15.8.1",
"resolve": "^2.0.0-next.5",
"semver": "^6.3.1",
"string.prototype.matchall": "^4.0.12",
"string.prototype.repeat": "^1.0.0"
},
"engines": {
"node": ">=4"
},
"peerDependencies": {
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
}
},
"node_modules/eslint-plugin-react-hooks": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
"integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-react/node_modules/brace-expansion": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/eslint-plugin-react/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/eslint-plugin-react/node_modules/resolve": {
"version": "2.0.0-next.5",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
"integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-core-module": "^2.13.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/eslint-plugin-react/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/eslint-plugin-unused-imports": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz",
@@ -10951,19 +10804,6 @@
"node": ">=10.13.0"
}
},
"node_modules/globals": {
"version": "15.15.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
"integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globalthis": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
@@ -11021,7 +10861,9 @@
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true,
"license": "MIT"
"license": "MIT",
"optional": true,
"peer": true
},
"node_modules/has-bigints": {
"version": "1.1.0",
@@ -11176,6 +11018,8 @@
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">= 4"
}
@@ -11739,24 +11583,6 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"license": "ISC"
},
"node_modules/iterator.prototype": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
"integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==",
"dev": true,
"license": "MIT",
"dependencies": {
"define-data-property": "^1.1.4",
"es-object-atoms": "^1.0.0",
"get-intrinsic": "^1.2.6",
"get-proto": "^1.0.0",
"has-symbols": "^1.1.0",
"set-function-name": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/jackspeak": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
@@ -13173,22 +12999,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object.entries": {
"version": "1.1.9",
"resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz",
"integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.4",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.fromentries": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
@@ -14421,6 +14231,8 @@
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
"license": "ISC",
"optional": true,
"peer": true,
"bin": {
"semver": "bin/semver.js"
},
@@ -14720,45 +14532,6 @@
"node": ">= 0.4"
}
},
"node_modules/string.prototype.matchall": {
"version": "4.0.12",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
"integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.3",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.6",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"get-intrinsic": "^1.2.6",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"internal-slot": "^1.1.0",
"regexp.prototype.flags": "^1.5.3",
"set-function-name": "^2.0.2",
"side-channel": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.repeat": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
"integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
"dev": true,
"license": "MIT",
"dependencies": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5"
}
},
"node_modules/string.prototype.trim": {
"version": "1.2.10",
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
@@ -15157,6 +14930,8 @@
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=18.12"
},

11
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "napcat",
"version": "4.9.21",
"version": "4.9.27",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "napcat",
"version": "4.9.21",
"version": "4.9.27",
"dependencies": {
"express": "^5.0.0",
"silk-wasm": "^3.6.1",
@@ -44,6 +44,7 @@
"express-rate-limit": "^7.5.0",
"fast-xml-parser": "^4.3.6",
"file-type": "^21.0.0",
"fs-extra": "^11.3.2",
"json5": "^2.2.3",
"multer": "^2.0.1",
"napcat.protobuf": "^1.1.4",
@@ -5222,9 +5223,9 @@
"license": "MIT"
},
"node_modules/fs-extra": {
"version": "11.3.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
"integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
"version": "11.3.2",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz",
"integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@@ -2,7 +2,7 @@
"name": "napcat",
"private": true,
"type": "module",
"version": "4.9.24",
"version": "4.9.27",
"scripts": {
"build:universal": "npm run build:webui && npm run dev:universal || exit 1",
"build:framework": "npm run build:webui && npm run dev:framework || exit 1",
@@ -23,7 +23,8 @@
"lint:webui": "cd napcat.webui && eslint src/**/*",
"lint:fix:webui": "cd napcat.webui && eslint --fix src/**/*",
"depend": "cd dist && npm install --omit=dev",
"dev:depend": "npm i && cd napcat.webui && npm i"
"dev:depend": "npm i && cd napcat.webui && npm i",
"test:winshell": "pwsh ./tests/nodeTest.ps1"
},
"devDependencies": {
"@babel/core": "^7.28.0",
@@ -57,6 +58,7 @@
"express-rate-limit": "^7.5.0",
"fast-xml-parser": "^4.3.6",
"file-type": "^21.0.0",
"fs-extra": "^11.3.2",
"json5": "^2.2.3",
"multer": "^2.0.1",
"napcat.protobuf": "^1.1.4",

View File

@@ -119,6 +119,9 @@ export function getDefaultQQVersionConfigInfo (): QQVersionConfigType {
}
export function getQQPackageInfoPath (exePath: string = '', version?: string): string {
if (process.env['NAPCAT_QQ_PACKAGE_INFO_PATH']) {
return process.env['NAPCAT_QQ_PACKAGE_INFO_PATH'];
}
let packagePath;
if (os.platform() === 'darwin') {
packagePath = path.join(path.dirname(exePath), '..', 'Resources', 'app', 'package.json');
@@ -135,6 +138,9 @@ export function getQQPackageInfoPath (exePath: string = '', version?: string): s
}
export function getQQVersionConfigPath (exePath: string = ''): string | undefined {
if (process.env['NAPCAT_QQ_VERSION_CONFIG_PATH']) {
return process.env['NAPCAT_QQ_VERSION_CONFIG_PATH'];
}
let configVersionInfoPath;
if (os.platform() === 'win32') {
configVersionInfoPath = path.join(path.dirname(exePath), 'versions', 'config.json');

View File

@@ -1 +1 @@
export const napCatVersion = '4.9.24';
export const napCatVersion = '4.9.27';

View File

@@ -43,6 +43,12 @@ export enum NapCatCoreWorkingEnv {
}
export function loadQQWrapper (QQVersion: string): WrapperNodeApi {
if (process.env['NAPCAT_WRAPPER_PATH']) {
const wrapperPath = process.env['NAPCAT_WRAPPER_PATH'];
const nativemodule: { exports: WrapperNodeApi; } = { exports: {} as WrapperNodeApi };
process.dlopen(nativemodule, wrapperPath);
return nativemodule.exports;
}
let appPath;
if (os.platform() === 'darwin') {
appPath = path.resolve(path.dirname(process.execPath), '../Resources/app');

View File

@@ -41,6 +41,30 @@ class GetGroupMemberInfo extends OneBotAction<Payload, OB11GroupMember> {
}
async _handle (payload: Payload) {
// 处理 @全体成员 的特殊情况,跳过 UID 转换直接返回
if (payload.user_id === 'all' || payload.user_id === '0') {
return {
group_id: +payload.group_id,
user_id: payload.user_id === 'all' ? 0 : +payload.user_id,
nickname: '全体成员',
card: '全体成员',
sex: 'unknown' as const,
age: 0,
area: '',
level: '0',
qq_level: 0,
join_time: 0,
last_sent_time: 0,
title_expire_time: 0,
unfriendly: false,
card_changeable: false,
is_robot: false,
shut_up_timestamp: 0,
role: 'member' as const,
title: '',
};
}
const isNocache = this.parseBoolean(payload.no_cache ?? true);
const uid = await this.getUid(payload.user_id);
const member = await this.getGroupMemberInfo(payload, uid, isNocache);

View File

@@ -24,7 +24,6 @@ import path from 'path';
import fs from 'fs';
import os from 'os';
import { LoginListItem, NodeIKernelLoginService } from '@/core/services';
import { program } from 'commander';
import qrcode from '@/qrcode/lib/main';
import { NapCatOneBot11Adapter } from '@/onebot';
import { InitWebUi } from '@/webui';
@@ -322,7 +321,9 @@ export async function NCoreInitShell () {
// 初始化 FFmpeg 服务
await FFmpegService.init(pathWrapper.binaryPath, logger);
await connectToNamedPipe(logger).catch(e => logger.logError('命名管道连接失败', e));
if (process.env['NAPCAT_DISABLE_PIPE'] !== '1') {
await connectToNamedPipe(logger).catch(e => logger.logError('命名管道连接失败', e));
}
const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
const wrapper = loadQQWrapper(basicInfoWrapper.getFullQQVersion());
const nativePacketHandler = new NativePacketHandler({ logger }); // 初始化 NativePacketHandler 用于后续使用
@@ -362,9 +363,18 @@ export async function NCoreInitShell () {
await initializeEngine(engine, basicInfoWrapper, dataPathGlobal, systemPlatform, systemVersion);
await initializeLoginService(loginService, basicInfoWrapper, dataPathGlobal, systemVersion, hostname);
handleProxy(session, logger);
program.option('-q, --qq [number]', 'QQ号').parse(process.argv);
const cmdOptions = program.opts();
const quickLoginUin = cmdOptions['qq'];
let quickLoginUin: string | undefined = undefined;
try {
const args = process.argv;
const qIndex = args.findIndex(arg => arg === '-q' || arg === '--qq');
if (qIndex !== -1 && qIndex + 1 < args.length) {
quickLoginUin = args[qIndex + 1];
}
} catch (error) {
logger.logWarn('解析命令行参数失败,无法使用快速登录功能', error);
}
const historyLoginList = (await loginService.getLoginList()).LocalLoginInfoList;
const dataTimestape = new Date().getTime().toString();

BIN
tests/QQNT.dll Normal file

Binary file not shown.

69
tests/loadNapCat.cjs Normal file
View File

@@ -0,0 +1,69 @@
const fs = require('fs-extra');
const path = require('path');
const { pathToFileURL } = require('url');
const mainPath = process.argv[2];
if (!mainPath) {
console.error('Please provide the base directory as the first argument.');
process.exit(1);
}
// 动态获取 versions 下唯一的版本文件夹,并拼接 resources/app 路径
const versionsDir = path.join(mainPath, 'versions');
console.log(`Looking for version folders in: ${versionsDir}`);
const versionFolders = fs.readdirSync(versionsDir).filter(f => fs.statSync(path.join(versionsDir, f)).isDirectory());
if (versionFolders.length !== 1) {
console.error('versions 文件夹下必须且只能有一个版本目录');
process.exit(1);
}
const BASE_DIR = path.join(versionsDir, versionFolders[0], 'resources', 'app');
const TARGET_DIR = path.join(__dirname, 'run');
const QQNT_FILE = path.join(__dirname, 'QQNT.dll');
const NAPCAT_MJS_PATH = path.join(__dirname, '..', 'dist', 'napcat.mjs');
const itemsToCopy = [
'avif_convert.dll',
'broadcast_ipc.dll',
'libglib-2.0-0.dll',
'libgobject-2.0-0.dll',
'libvips-42.dll',
'ncnn.dll',
'opencv.dll',
'package.json',
'QBar.dll',
'wrapper.node'
];
async function copyAll () {
const qqntDllPath = path.join(TARGET_DIR, 'QQNT.dll');
const configPath = path.join(TARGET_DIR, 'config.json');
const allItemsExist = await fs.pathExists(qqntDllPath)
&& await fs.pathExists(configPath)
&& (await Promise.all(itemsToCopy.map(item => fs.pathExists(path.join(TARGET_DIR, item))))).every(exists => exists);
if (!allItemsExist) {
console.log('Copying required files...');
await fs.ensureDir(TARGET_DIR);
await fs.copy(QQNT_FILE, qqntDllPath, { overwrite: true });
await fs.copy(path.join(versionsDir, 'config.json'), configPath, { overwrite: true });
await Promise.all(itemsToCopy.map(async (item) => {
await fs.copy(path.join(BASE_DIR, item), path.join(TARGET_DIR, item), { overwrite: true });
console.log(`Copied ${item}`);
}));
console.log('All files copied successfully.');
} else {
console.log('Files already exist, skipping copy.');
}
process.env.NAPCAT_WRAPPER_PATH = path.join(TARGET_DIR, 'wrapper.node');
process.env.NAPCAT_QQ_PACKAGE_INFO_PATH = path.join(TARGET_DIR, 'package.json');
process.env.NAPCAT_QQ_VERSION_CONFIG_PATH = path.join(TARGET_DIR, 'config.json');
process.env.NAPCAT_DISABLE_PIPE = '1';
process.env.NAPCAT_WORKDIR = path.join(__dirname, 'run');
console.log('Loading NapCat module...');
await import(pathToFileURL(NAPCAT_MJS_PATH).href);
}
copyAll().catch(console.error);

8
tests/nodeTest.ps1 Normal file
View File

@@ -0,0 +1,8 @@
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$regPath = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ'
$uninstall = (Get-ItemProperty -Path $regPath -Name UninstallString -ErrorAction Stop).UninstallString
$uninstall = $uninstall.Trim('"')
$qqPath = Split-Path $uninstall -Parent
Write-Host "QQPath: $qqPath"
node.exe "tests/loadNapCat.cjs" "$qqPath"