diff --git a/manifest.json b/manifest.json index feb9346..51eb7ce 100644 --- a/manifest.json +++ b/manifest.json @@ -1,10 +1,10 @@ { "manifest_version": 4, "type": "extension", - "name": "LLOneBot", + "name": "LLOneBot v3.10.2", "slug": "LLOneBot", "description": "LiteLoaderQQNT的OneBotApi", - "version": "3.10.1", + "version": "3.10.2", "thumbnail": "./icon.png", "authors": [ { @@ -30,4 +30,4 @@ "main": "./main.js", "preload": "./preload.js" } -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 80b5b5a..173fab6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,12 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "audio-buffer-from": "^1.1.1", "express": "^4.18.2", "fluent-ffmpeg": "^2.1.2", "json-bigint": "^1.0.0", "music-metadata": "^8.1.4", "silk-wasm": "^3.2.3", + "utf-8-validate": "^6.0.3", "uuid": "^9.0.1", "ws": "^8.16.0" }, @@ -22,14 +22,14 @@ "@babel/preset-env": "^7.23.2", "@types/express": "^4.17.20", "@types/fluent-ffmpeg": "^2.1.24", - "@types/node": "^20.11.19", + "@types/node": "^20.11.24", "@types/uuid": "^9.0.8", "@types/ws": "^8.5.10", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^12.0.2", - "cross-env": "^7.0.3", "electron": "^29.0.1", "ts-loader": "^9.5.0", + "ts-node": "^10.9.2", "typescript": "^5.2.2", "webpack": "^5.89.0", "webpack-cli": "^5.1.4" @@ -2007,6 +2007,28 @@ "node": ">=4" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://mirrors.cloud.tencent.com/npm/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -2203,6 +2225,30 @@ "resolved": "https://mirrors.cloud.tencent.com/npm/@tokenizer/token/-/token-0.3.0.tgz", "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://mirrors.cloud.tencent.com/npm/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://mirrors.cloud.tencent.com/npm/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://mirrors.cloud.tencent.com/npm/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://mirrors.cloud.tencent.com/npm/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "node_modules/@types/body-parser": { "version": "1.19.4", "resolved": "https://mirrors.cloud.tencent.com/npm/@types/body-parser/-/body-parser-1.19.4.tgz", @@ -2327,9 +2373,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.19", - "resolved": "https://mirrors.cloud.tencent.com/npm/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "version": "20.11.24", + "resolved": "https://mirrors.cloud.tencent.com/npm/@types/node/-/node-20.11.24.tgz", + "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -2637,6 +2683,15 @@ "acorn": "^8" } }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2716,6 +2771,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://mirrors.cloud.tencent.com/npm/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://mirrors.cloud.tencent.com/npm/array-flatten/-/array-flatten-1.1.1.tgz", @@ -2726,51 +2787,6 @@ "resolved": "https://mirrors.cloud.tencent.com/npm/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" }, - "node_modules/atob-lite": { - "version": "2.0.0", - "resolved": "https://mirrors.cloud.tencent.com/npm/atob-lite/-/atob-lite-2.0.0.tgz", - "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=" - }, - "node_modules/audio-buffer": { - "version": "4.0.4", - "resolved": "https://mirrors.cloud.tencent.com/npm/audio-buffer/-/audio-buffer-4.0.4.tgz", - "integrity": "sha512-phH+MR3G+N/PO5ZKKxx7HlU6vJwAJFa0+FCaTjr/4lUZU/RCjUTqlk3nMJTRy5+b+6cbx8m//EtwZOVI5Ht9+w==", - "dependencies": { - "audio-context": "^1.0.0" - } - }, - "node_modules/audio-buffer-from": { - "version": "1.1.1", - "resolved": "https://mirrors.cloud.tencent.com/npm/audio-buffer-from/-/audio-buffer-from-1.1.1.tgz", - "integrity": "sha512-8Wcira24z+26GXDFe7ZFRF1bJm1iWrz8O+XL8iNZxZjxqAPXIoK1IrJiOqStv35ASPbRjG57ZK/T0WO92MDUSg==", - "dependencies": { - "audio-buffer": "^4.0.4", - "audio-context": "^1.0.1", - "audio-format": "^2.0.0", - "is-audio-buffer": "^1.0.11", - "is-plain-obj": "^1.1.0", - "pcm-convert": "^1.6.0", - "pick-by-alias": "^1.2.0", - "string-to-arraybuffer": "^1.0.0" - } - }, - "node_modules/audio-context": { - "version": "1.0.3", - "resolved": "https://mirrors.cloud.tencent.com/npm/audio-context/-/audio-context-1.0.3.tgz", - "integrity": "sha512-RH3/rM74f2ITlohhjgC7oYZVS97wtv/SEjXLCzEinnrIPIDxc39m2aFc6wmdkM0NYRKo1DMleYPMAIbnTRW0eA==" - }, - "node_modules/audio-format": { - "version": "2.3.2", - "resolved": "https://mirrors.cloud.tencent.com/npm/audio-format/-/audio-format-2.3.2.tgz", - "integrity": "sha512-5IA2grZhaVhpGxX6lbJm8VVh/SKQULMXXrFxuiodi0zhzDPRB8BJfieo89AclEQv4bDxZRH4lv06qNnxqkFhKQ==", - "dependencies": { - "is-audio-buffer": "^1.0.11", - "is-buffer": "^1.1.5", - "is-plain-obj": "^1.1.0", - "pick-by-alias": "^1.2.0", - "sample-rate": "^2.0.0" - } - }, "node_modules/babel-loader": { "version": "9.1.3", "resolved": "https://mirrors.cloud.tencent.com/npm/babel-loader/-/babel-loader-9.1.3.tgz", @@ -3282,23 +3298,11 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://mirrors.cloud.tencent.com/npm/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -3413,6 +3417,15 @@ "dev": true, "optional": true }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://mirrors.cloud.tencent.com/npm/ee-first/-/ee-first-1.1.1.tgz", @@ -4302,21 +4315,6 @@ "node": ">= 0.10" } }, - "node_modules/is-audio-buffer": { - "version": "1.1.0", - "resolved": "https://mirrors.cloud.tencent.com/npm/is-audio-buffer/-/is-audio-buffer-1.1.0.tgz", - "integrity": "sha512-fmPC/dizJmP4ITCsW5oTQGMJ9wZVE+A/zAe6FQo3XwgERxmXHmm3ON5XkWDAxmyxvsrDmWx3NArpSgamp/59AA==" - }, - "node_modules/is-base64": { - "version": "0.1.0", - "resolved": "https://mirrors.cloud.tencent.com/npm/is-base64/-/is-base64-0.1.0.tgz", - "integrity": "sha512-WRRyllsGXJM7ZN7gPTCCQ/6wNPTRDwiWdPK66l5sJzcU/oOzcIcRRf0Rux8bkpox/1yjt0F6VJRsQOIG2qz5sg==" - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://mirrors.cloud.tencent.com/npm/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", @@ -4359,14 +4357,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://mirrors.cloud.tencent.com/npm/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -4541,6 +4531,12 @@ "node": ">=10" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://mirrors.cloud.tencent.com/npm/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/matcher": { "version": "3.0.0", "resolved": "https://mirrors.cloud.tencent.com/npm/matcher/-/matcher-3.0.0.tgz", @@ -4715,8 +4711,6 @@ "version": "4.8.0", "resolved": "https://mirrors.cloud.tencent.com/npm/node-gyp-build/-/node-gyp-build-4.8.0.tgz", "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", - "optional": true, - "peer": true, "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -4750,14 +4744,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://mirrors.cloud.tencent.com/npm/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://mirrors.cloud.tencent.com/npm/object-inspect/-/object-inspect-1.13.1.tgz", @@ -4890,17 +4876,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pcm-convert": { - "version": "1.6.5", - "resolved": "https://mirrors.cloud.tencent.com/npm/pcm-convert/-/pcm-convert-1.6.5.tgz", - "integrity": "sha512-5CEspU4j8aEQ80AhNbcLfpT0apc93E6endFxahWd4sV70I6PN7LPdz8GoYm/1qr400K9bUVsVA+KxNgbFROZPw==", - "dependencies": { - "audio-format": "^2.3.2", - "is-audio-buffer": "^1.0.11", - "is-buffer": "^1.1.5", - "object-assign": "^4.1.1" - } - }, "node_modules/peek-readable": { "version": "5.0.0", "resolved": "https://mirrors.cloud.tencent.com/npm/peek-readable/-/peek-readable-5.0.0.tgz", @@ -4919,11 +4894,6 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, - "node_modules/pick-by-alias": { - "version": "1.2.0", - "resolved": "https://mirrors.cloud.tencent.com/npm/pick-by-alias/-/pick-by-alias-1.2.0.tgz", - "integrity": "sha1-X3yysfIabh6ISgyHhVqko3NhEHs=" - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://mirrors.cloud.tencent.com/npm/picocolors/-/picocolors-1.0.0.tgz", @@ -5316,11 +5286,6 @@ "resolved": "https://mirrors.cloud.tencent.com/npm/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/sample-rate": { - "version": "2.0.1", - "resolved": "https://mirrors.cloud.tencent.com/npm/sample-rate/-/sample-rate-2.0.1.tgz", - "integrity": "sha512-AIK0vVBiAEObmpJOxQu/WCyklnWGqzTSDII4O7nBo+SJHmfgBUiYhgV/Y3Ohz76gfSlU6R5CIAKggj+nAOLSvg==" - }, "node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -5552,15 +5517,6 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string-to-arraybuffer": { - "version": "1.0.2", - "resolved": "https://mirrors.cloud.tencent.com/npm/string-to-arraybuffer/-/string-to-arraybuffer-1.0.2.tgz", - "integrity": "sha512-DaGZidzi93dwjQen5I2osxR9ERS/R7B1PFyufNMnzhj+fmlDQAc1DSDIJVJhgI8Oq221efIMbABUBdPHDRt43Q==", - "dependencies": { - "atob-lite": "^2.0.0", - "is-base64": "^0.1.0" - } - }, "node_modules/strtok3": { "version": "7.0.0", "resolved": "https://mirrors.cloud.tencent.com/npm/strtok3/-/strtok3-7.0.0.tgz", @@ -5765,6 +5721,49 @@ "node": ">= 8" } }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://mirrors.cloud.tencent.com/npm/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, "node_modules/type-fest": { "version": "0.13.1", "resolved": "https://mirrors.cloud.tencent.com/npm/type-fest/-/type-fest-0.13.1.tgz", @@ -5922,8 +5921,6 @@ "resolved": "https://mirrors.cloud.tencent.com/npm/utf-8-validate/-/utf-8-validate-6.0.3.tgz", "integrity": "sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==", "hasInstallScript": true, - "optional": true, - "peer": true, "dependencies": { "node-gyp-build": "^4.3.0" }, @@ -5956,6 +5953,12 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://mirrors.cloud.tencent.com/npm/vary/-/vary-1.1.2.tgz", @@ -6164,6 +6167,15 @@ "fd-slicer": "~1.1.0" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://mirrors.cloud.tencent.com/npm/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "1.0.0", "resolved": "https://mirrors.cloud.tencent.com/npm/yocto-queue/-/yocto-queue-1.0.0.tgz", diff --git a/package.json b/package.json index 2640e6f..a23fd1f 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "build-main": "webpack --config webpack.main.config.js", "build-preload": "webpack --config webpack.preload.config.js", "build-renderer": "webpack --config webpack.renderer.config.js", + "build-version": "ts-node ./scripts/gen-version.ts", "build-mac": "npm run build && cp manifest.json dist/ && npm run deploy-mac", "deploy-mac": "cp -r dist/* ~/Library/Containers/com.tencent.qq/Data/LiteLoaderQQNT/plugins/LLOnebot/", "build-win": "npm run build && cp manifest.json dist/ && npm run deploy-win", @@ -30,13 +31,14 @@ "@babel/preset-env": "^7.23.2", "@types/express": "^4.17.20", "@types/fluent-ffmpeg": "^2.1.24", - "@types/node": "^20.11.19", + "@types/node": "^20.11.24", "@types/uuid": "^9.0.8", "@types/ws": "^8.5.10", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^12.0.2", "electron": "^29.0.1", "ts-loader": "^9.5.0", + "ts-node": "^10.9.2", "typescript": "^5.2.2", "webpack": "^5.89.0", "webpack-cli": "^5.1.4" diff --git a/scripts/gen-version.ts b/scripts/gen-version.ts new file mode 100644 index 0000000..d401cfe --- /dev/null +++ b/scripts/gen-version.ts @@ -0,0 +1,18 @@ +import fs = require("fs"); +import path = require("path"); +import {version} from "../src/version"; +const manifestPath = path.join(__dirname, "../manifest.json"); +function readManifest(): any{ + if (fs.existsSync(manifestPath)){ + return JSON.parse(fs.readFileSync(manifestPath, "utf-8")); + } +} + +function writeManifest(manifest: any){ + fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2)); +} + +let manifest = readManifest(); +manifest.version = version; +manifest.name = `LLOneBot v${version}`; +writeManifest(manifest); \ No newline at end of file diff --git a/src/common/data.ts b/src/common/data.ts index 004d4f6..4d29b65 100644 --- a/src/common/data.ts +++ b/src/common/data.ts @@ -5,7 +5,6 @@ import {LLOneBotError} from "./types"; export let groups: Group[] = [] export let friends: Friend[] = [] export let msgHistory: Record = {} // msgId: RawMessage -export const version = "3.10.1" export let groupNotifies: Map = new Map(); export let friendRequests: Map = new Map(); export let llonebotError: LLOneBotError = { diff --git a/src/common/utils.ts b/src/common/utils.ts index e150c3c..ec9e6d1 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -2,10 +2,9 @@ import * as path from "path"; import {selfInfo} from "./data"; import {ConfigUtil} from "./config"; import util from "util"; -import {encode, getDuration} from "silk-wasm"; +import {encode, getDuration, isWav} from "silk-wasm"; import fs from 'fs'; import {v4 as uuidv4} from "uuid"; -import {exec} from "node:child_process"; import ffmpeg from "fluent-ffmpeg" export const CONFIG_DIR = global.LiteLoader.plugins["LLOneBot"].path.data; @@ -138,17 +137,20 @@ export function mergeNewProperties(newObj: any, oldObj: any) { }); } -export function checkFFMPEG(newPath: string=null): Promise { +export function checkFfmpeg(newPath: string = null): Promise { return new Promise((resolve, reject) => { - const ffmpegPath = newPath || 'ffmpeg' - exec(ffmpegPath + ' -version', (error, stdout, stderr) => { - if (error) { - log('ffmpeg is not installed or not found in PATH:', error); - resolve(false) - } - log('ffmpeg is installed. Version info:', stdout); - resolve(true); - }); + if (newPath) { + ffmpeg.setFfmpegPath(newPath); + ffmpeg.getAvailableFormats((err, formats) => { + if (err) { + log('ffmpeg is not installed or not found in PATH:', err); + resolve(false) + } else { + log('ffmpeg is installed.'); + resolve(true); + } + }) + } }); } @@ -172,33 +174,8 @@ export async function encodeSilk(filePath: string) { } } - function isWavFile(filePath: string) { - return new Promise((resolve, reject) => { - fs.open(filePath, 'r', (err, fd) => { - if (err) { - reject(err); - return; - } - // 读取前12个字节 - const buffer = Buffer.alloc(12); - fs.read(fd, buffer, 0, 12, 0, (err, bytesRead, buffer) => { - if (err) { - reject(err); - return; - } - fs.close(fd, (err) => { - if (err) { - reject(err); - return; - } - // 检查RIFF头和WAVE格式标识 - const isRIFF = buffer.toString('utf8', 0, 4) === 'RIFF'; - const isWAVE = buffer.toString('utf8', 8, 12) === 'WAVE'; - resolve(isRIFF && isWAVE); - }); - }); - }); - }); + async function isWavFile(filePath: string) { + return isWav(fs.readFileSync(filePath)); } async function getAudioSampleRate(filePath: string) { @@ -217,15 +194,15 @@ export async function encodeSilk(filePath: string) { const fileName = path.basename(filePath); const pttPath = path.join(CONFIG_DIR, uuidv4()); if (getFileHeader(filePath) !== "02232153494c4b") { - log(`语音文件${filePath}需要转换`) + log(`语音文件${filePath}需要转换成silk`) const isWav = await isWavFile(filePath); + const wavPath = pttPath + ".wav" if (!isWav) { log(`语音文件${filePath}正在转换成wav`) // let voiceData = await fsp.readFile(filePath) - const wavPath = pttPath + ".wav" await new Promise((resolve, reject) => { const ffmpegPath = getConfigUtil().getConfig().ffmpeg; - if (ffmpegPath){ + if (ffmpegPath) { ffmpeg.setFfmpegPath(ffmpegPath); } ffmpeg(filePath).toFormat("wav").on('end', function () { @@ -236,31 +213,32 @@ export async function encodeSilk(filePath: string) { reject(err); }) .save(wavPath) - .on("end", ()=>{ + .on("end", () => { filePath = wavPath resolve(wavPath); }); }) - const sampleRate = await getAudioSampleRate(filePath) || 44100; - const pcm = fs.readFileSync(filePath); - const silk = await encode(pcm, sampleRate); - fs.writeFileSync(pttPath, silk.data); - fs.unlink(wavPath, (err) => {}); - log(`语音文件${filePath}转换成功!`, pttPath) - return { - converted: true, - path: pttPath, - duration: silk.duration, - }; - } else { - const pcm = fs.readFileSync(filePath); - const duration = getDuration(pcm); - return { - converted: false, - path: filePath, - duration: duration, - }; } + const sampleRate = await getAudioSampleRate(filePath) || 44100; + const pcm = fs.readFileSync(filePath); + const silk = await encode(pcm, sampleRate); + fs.writeFileSync(pttPath, silk.data); + fs.unlink(wavPath, (err) => { + }); + log(`语音文件${filePath}转换成功!`, pttPath) + return { + converted: true, + path: pttPath, + duration: silk.duration, + }; + } else { + const pcm = fs.readFileSync(filePath); + const duration = getDuration(pcm); + return { + converted: false, + path: filePath, + duration: duration, + }; } } catch (error) { log("convert silk failed", error.stack); diff --git a/src/main/main.ts b/src/main/main.ts index 413d4b1..fe0f81f 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -1,7 +1,7 @@ // 运行在 Electron 主进程 下的插件入口 import {BrowserWindow, dialog, ipcMain} from 'electron'; -import fs from 'fs'; +import * as fs from 'fs'; import {Config} from "../common/types"; import { CHANNEL_ERROR, @@ -11,7 +11,7 @@ import { CHANNEL_SET_CONFIG, } from "../common/channels"; import {ob11WebsocketServer} from "../onebot11/server/ws/WebsocketServer"; -import {checkFFMPEG, CONFIG_DIR, getConfigUtil, log} from "../common/utils"; +import {checkFfmpeg, CONFIG_DIR, getConfigUtil, log} from "../common/utils"; import { addHistoryMsg, friendRequests, @@ -140,8 +140,10 @@ function onLoad() { // 检查ffmpeg if (arg.ffmpeg) { - checkFFMPEG(arg.ffmpeg).then(success => { - llonebotError.ffmpegError = '' + checkFfmpeg(arg.ffmpeg).then(success => { + if (success){ + llonebotError.ffmpegError = '' + } }) } @@ -341,7 +343,7 @@ function onLoad() { NTQQApi.getGroups(true).then() const config = getConfigUtil().getConfig() // 检查ffmpeg - checkFFMPEG(config.ffmpeg).then(exist => { + checkFfmpeg(config.ffmpeg).then(exist => { if (!exist) { llonebotError.ffmpegError = `没有找到ffmpeg,音频只能发送wav和silk` } diff --git a/src/ntqqapi/constructor.ts b/src/ntqqapi/constructor.ts index 0187bb6..0187c58 100644 --- a/src/ntqqapi/constructor.ts +++ b/src/ntqqapi/constructor.ts @@ -10,7 +10,7 @@ import { } from "./types"; import {NTQQApi} from "./ntcall"; import {encodeSilk} from "../common/utils"; -import fs from "fs"; +import * as fs from "fs"; export class SendMsgElementConstructor { diff --git a/src/ntqqapi/types.ts b/src/ntqqapi/types.ts index 2d3f485..39a675a 100644 --- a/src/ntqqapi/types.ts +++ b/src/ntqqapi/types.ts @@ -277,6 +277,7 @@ export interface RawMessage { recallTime: string; // 撤回时间, "0"是没有撤回 elements: { elementId: string, + elementType: ElementType; replyElement: { senderUid: string; // 原消息发送者QQ号 sourceMsgIsIncPic: boolean; // 原消息是否有图片 diff --git a/src/onebot11/action/GetVersionInfo.ts b/src/onebot11/action/GetVersionInfo.ts index 83ba16b..db43122 100644 --- a/src/onebot11/action/GetVersionInfo.ts +++ b/src/onebot11/action/GetVersionInfo.ts @@ -1,7 +1,7 @@ import BaseAction from "./BaseAction"; import {OB11Version} from "../types"; -import {version} from "../../common/data"; import {ActionName} from "./types"; +import {version} from "../../version"; export default class GetVersionInfo extends BaseAction{ actionName = ActionName.GetVersionInfo diff --git a/src/onebot11/action/SendMsg.ts b/src/onebot11/action/SendMsg.ts index 86dde3d..f877697 100644 --- a/src/onebot11/action/SendMsg.ts +++ b/src/onebot11/action/SendMsg.ts @@ -1,4 +1,4 @@ -import {AtType, ChatType, Group, SendMessageElement} from "../../ntqqapi/types"; +import {AtType, ChatType, Group, RawMessage, SendMessageElement} from "../../ntqqapi/types"; import {addHistoryMsg, friends, getGroup, getHistoryMsgByShortId, getUidByUin, selfInfo,} from "../../common/data"; import {OB11MessageData, OB11MessageDataType, OB11MessageMixType, OB11MessageNode, OB11PostSendMsg} from '../types'; import {NTQQApi, Peer} from "../../ntqqapi/ntcall"; @@ -8,9 +8,7 @@ import BaseAction from "./BaseAction"; import {ActionName, BaseCheckResult} from "./types"; import * as fs from "fs"; import {log} from "../../common/utils"; -import {v4 as uuidv4} from "uuid" import {decodeCQCode} from "../cqcode"; -import {Send} from "express"; function checkSendMessage(sendMsgList: OB11MessageData[]) { function checkUri(uri: string): boolean { @@ -145,7 +143,8 @@ export class SendMsg extends BaseAction { chatType: ChatType.friend, peerUid: selfInfo.uid } - let nodeIds: string[] = [] + let selfNodeMsgList: RawMessage[] = []; + let originalNodeMsgList: RawMessage[] = []; for (const messageNode of messageNodes) { // 一个node表示一个人的消息 let nodeId = messageNode.data.id; @@ -153,7 +152,7 @@ export class SendMsg extends BaseAction { if (nodeId) { let nodeMsg = getHistoryMsgByShortId(nodeId); if (nodeMsg) { - nodeIds.push(nodeMsg.msgId); + originalNodeMsgList.push(nodeMsg); } } else { // 自定义的消息 @@ -165,7 +164,7 @@ export class SendMsg extends BaseAction { } = await this.createSendElements(this.convertMessage2List(messageNode.data.content), group); log("开始生成转发节点", sendElements); const nodeMsg = await this.send(selfPeer, sendElements, deleteAfterSentFiles, true); - nodeIds.push(nodeMsg.msgId) + selfNodeMsgList.push(nodeMsg); log("转发节点生成成功", nodeMsg.msgId); } catch (e) { log("生效转发消息节点失败", e) @@ -173,9 +172,49 @@ export class SendMsg extends BaseAction { } } + let nodeIds: string[] = [] + // 检查是否需要克隆直接引用消息id的节点 + let needSendSelf = false; + if (selfNodeMsgList.length) { + needSendSelf = true + } else { + needSendSelf = !originalNodeMsgList.every((msg, index) => msg.peerUid === originalNodeMsgList[0].peerUid) + } + if (needSendSelf) { + nodeIds = selfNodeMsgList.map(msg => msg.msgId); + for (const originalNodeMsg of originalNodeMsgList) { + if (originalNodeMsg.peerUid === selfInfo.uid) { + nodeIds.push(originalNodeMsg.msgId) + } else { // 需要进行克隆 + let sendElements: SendMessageElement[] = [] + Object.keys(originalNodeMsg.elements).forEach((eleKey) => { + if (eleKey !== "elementId") { + sendElements.push(originalNodeMsg.elements[eleKey]) + } + }) + try { + const nodeMsg = await NTQQApi.sendMsg(selfPeer, sendElements, true); + nodeIds.push(nodeMsg.msgId) + log("克隆转发消息成功") + } catch (e) { + log("克隆转发消息失败", e) + } + } + } + } else { + nodeIds = originalNodeMsgList.map(msg => msg.msgId) + } + + let srcPeer = selfPeer; + if (!needSendSelf) { + srcPeer = { + chatType: originalNodeMsgList[0].chatType === ChatType.group ? ChatType.group : ChatType.friend, + peerUid: originalNodeMsgList[0].peerUid + } + } // 开发转发 try { - return await NTQQApi.multiForwardMsg(selfPeer, destPeer, nodeIds) + return await NTQQApi.multiForwardMsg(srcPeer, destPeer, nodeIds) } catch (e) { log("forward failed", e) return null; diff --git a/src/version.ts b/src/version.ts new file mode 100644 index 0000000..81353a2 --- /dev/null +++ b/src/version.ts @@ -0,0 +1 @@ +export const version = "3.10.2" \ No newline at end of file