release: 2.2.0

This commit is contained in:
手瓜一十雪 2024-08-23 10:55:19 +08:00
parent 5e65ae76ad
commit 89c102513d
8 changed files with 146 additions and 108 deletions

View File

@ -30,34 +30,34 @@ jobs:
ls ls
node ./script/checkVersion.cjs node ./script/checkVersion.cjs
sh ./checkVersion.sh sh ./checkVersion.sh
# Build-LiteLoader: Build-LiteLoader:
# needs: [check-version] needs: [check-version]
# runs-on: ubuntu-latest runs-on: ubuntu-latest
# steps: steps:
# - name: Clone Main Repository - name: Clone Main Repository
# uses: actions/checkout@v4 uses: actions/checkout@v4
# with: with:
# repository: 'NapNeko/NapCatQQ' repository: 'NapNeko/NapCatQQ'
# submodules: true submodules: true
# ref: main ref: main
# token: ${{ secrets.NAPCAT_BUILD }} token: ${{ secrets.NAPCAT_BUILD }}
# - name: Use Node.js 20.X - name: Use Node.js 20.X
# uses: actions/setup-node@v4 uses: actions/setup-node@v4
# with: with:
# node-version: 20.x node-version: 20.x
# - name: Build NuCat Framework - name: Build NuCat Framework
# run: | run: |
# npm i npm i
# npm run build:framework npm run build:framework
# cd dist cd dist
# npm i --omit=dev npm i --omit=dev
# cd .. cd ..
# - name: Upload Artifact - name: Upload Artifact
# uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
# with: with:
# name: NapCat.Framework name: NapCat.Framework
# path: dist path: dist
Build-Shell: Build-Shell:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [check-version] needs: [check-version]
@ -90,31 +90,30 @@ jobs:
path: dist path: dist
release-napcat: release-napcat:
needs: [Build-Shell] needs: [Build-LiteLoader,Build-Shell]
# needs: [Build-LiteLoader,Build-Shell]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Download All Artifact - name: Download All Artifact
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
- name: Compress subdirectories
run: |
cd ./NapCat.Shell/
zip -q -r NapCat.Shell.zip *
cd ..
rm ./NapCat.Shell.zip -rf
mv ./NapCat.Shell/NapCat.Shell.zip ./
# - name: Compress subdirectories # - name: Compress subdirectories
# run: | # run: |
# cd ./NapCat.Shell/ # cd ./NapCat.Shell/
# zip -q -r NapCat.Shell.zip * # zip -q -r NapCat.Shell.zip *
# cd .. # cd ..
# cd ./NapCat.Framework/
# zip -q -r NapCat.Framework.zip *
# cd ..
# rm ./NapCat.Shell.zip -rf # rm ./NapCat.Shell.zip -rf
# rm ./NapCat.Framework.zip -rf
# mv ./NapCat.Shell/NapCat.Shell.zip ./ # mv ./NapCat.Shell/NapCat.Shell.zip ./
# mv ./NapCat.Framework/NapCat.Framework.zip ./ - name: Compress subdirectories
run: |
cd ./NapCat.Shell/
zip -q -r NapCat.Shell.zip *
cd ..
cd ./NapCat.Framework/
zip -q -r NapCat.Framework.zip *
cd ..
rm ./NapCat.Shell.zip -rf
rm ./NapCat.Framework.zip -rf
mv ./NapCat.Shell/NapCat.Shell.zip ./
mv ./NapCat.Framework/NapCat.Framework.zip ./
- name: Extract version from tag - name: Extract version from tag
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
@ -128,5 +127,6 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
body_path: CHANGELOG.md body_path: CHANGELOG.md
files: | files: |
NapCat.Framework.zip
NapCat.Shell.zip NapCat.Shell.zip
draft: true draft: true

View File

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

View File

@ -2,7 +2,7 @@
"name": "napcat", "name": "napcat",
"private": true, "private": true,
"type": "module", "type": "module",
"version": "2.1.0", "version": "2.2.0",
"scripts": { "scripts": {
"build:framework": "vite build --mode framework", "build:framework": "vite build --mode framework",
"build:shell": "vite build --mode shell", "build:shell": "vite build --mode shell",
@ -48,7 +48,7 @@
"ajv": "^8.13.0", "ajv": "^8.13.0",
"async-mutex": "^0.5.0", "async-mutex": "^0.5.0",
"chalk": "^5.3.0", "chalk": "^5.3.0",
"commander": "^12.1.0", "commander": "^12.2.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^5.0.0-beta.2", "express": "^5.0.0-beta.2",
"fast-xml-parser": "^4.3.6", "fast-xml-parser": "^4.3.6",

View File

@ -2,7 +2,7 @@ import path, { dirname } from 'path';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import fs from 'fs'; import fs from 'fs';
export const napcat_version = '2.1.0'; export const napcat_version = '2.2.0';
export class NapCatPathWrapper { export class NapCatPathWrapper {
binaryPath: string; binaryPath: string;

View File

@ -1,82 +1,120 @@
// https://github.com/NapNeko/LiteLoader-NapCatExample/blob/main/src/common/proxy.ts // 用于 NapCat 对QQ流程分析
// By Mlikiowa let Process = require('process');
let os = require('os');
let path = require('path');
Process.dlopenOrig = Process.dlopen;
const process = require('process'); let RealWrapper;
const os = require('os'); let loginService;
const path = require('path');
//Fuck LoginService
class LoginService {
constructor() {
console.log('[NapCat] Fuck LoginService Loading...');
}
}
//NapCat 专有逻辑
let initCallBack;
let wrapperSession;
let wrapperLoginService;
const currentPath = path.dirname(__filename); const currentPath = path.dirname(__filename);
const dlopenOrig = process.dlopen; function CreateFuckService(ServiceName) {
return new Proxy(() => { }, {
get: function (target, FunctionName, receiver) {
console.log("Proxy... Event:", ServiceName + '/' + FunctionName);
if (ServiceName == 'NodeIKernelLoginService' && FunctionName == 'get') {
return function () {
let ret = new Proxy(new LoginService(), {
get: function (target, ClassFunName, receiver) {
return function () {
let ret = loginService[ClassFunName](...arguments);
// if (ret instanceof Promise) {
// ret.then((data) => {
// console.log("Called ", '实例方法 NodeIKernelLoginService/' + ClassFunName, ' 参数:', ...arguments, '返回:', data);
// });
// } else {
// console.log("Called ", '实例方法 NodeIKernelLoginService/' + ClassFunName, ' 参数:', ...arguments, '返回:', ret);
// }
return ret;
}
let wrapperSession; }
let wrapperNodeApi; })
let wrapperLoginService; return ret;
let initCallBack; }
}
// Proxy dlopen if (ServiceName == 'NodeIQQNTWrapperSession' && FunctionName == 'create') {
process.dlopen = (module, filename, flags = os.constants.dlopen.RTLD_LAZY) => { return new Proxy(() => { }, {
dlopenOrig(module, filename, flags); apply: function (target, thisArg, argArray) {
for (const export_name in module.exports) { let Session = RealWrapper.NodeIQQNTWrapperSession[FunctionName](...argArray);
module.exports[export_name] = new Proxy(module.exports[export_name], { //传递Session
construct: (target, args, _newTarget) => { wrapperSession = Session;
let constructed;
if (export_name === 'NodeIKernelSessionListener') { let ret = new Proxy(Session, {
let HookedArg = []; get: function (target, ClassFunName, receiver) {
for (let ArgIndex in args) { return function () {
if (args[ArgIndex] instanceof Object) { if (ClassFunName == 'init') {
let HookArg = {}; let origin = arguments[3].onSessionInitComplete;
for (let ListenerName in args[ArgIndex]) { arguments[3].onSessionInitComplete = function () {
HookArg[ListenerName] = function (...ListenerData) { //console.log("Listner ", '注册方法 NodeIKernelSessionListener/onSessionInitComplete', ' 参数:', ...arguments);
try { origin(...arguments);
if (ListenerName === 'onSessionInitComplete') { initCallBack.forEach((cb) => cb(...arguments));
//回调成功
initCallBack.forEach((cb) => cb(...ListenerData));
clearHook(); clearHook();
} }
//console.log("Construct-ARG-Apply", ListenerName, JSON.stringify(ListenerData, null, 2));
} catch (error) {
// ignored
} }
args[ArgIndex][ListenerName](...ListenerData); let ret = Session[ClassFunName](...arguments);
}; // if (ret instanceof Promise) {
HookedArg.push(HookArg); // ret.then((data) => {
// console.log("Called ", '实例方法 NodeIQQNTWrapperSession/' + ClassFunName, ' 参数:', ...arguments, '返回:', data);
// });
// } else {
// console.log("Called ", '实例方法 NodeIQQNTWrapperSession/' + ClassFunName, ' 参数:', ...arguments, '返回:', ret);
// }
return ret;
}
} }
} else { });
// 其它类型 return ret;
//console.log("Construct-ARG-NotProxy", args[keyArg]);
}
} }
constructed = new target(...HookedArg); });
} else { }
constructed = new target(...args); }
}
if (export_name === 'NodeIQQNTWrapperSession') wrapperSession = constructed;
if (export_name === 'NodeIKernelLoginService') wrapperLoginService = constructed;
return constructed;
},
});
}
if (filename.toLowerCase().includes('wrapper.node')) {
wrapperNodeApi = module.exports;
} }
);
}
Process.dlopen = function (module, filename, flags = os.constants.dlopen.RTLD_LAZY) {
let dlopenRet = this.dlopenOrig(module, filename, flags);
if (filename.indexOf('wrapper.node') == -1) return dlopenRet;
//仅对Wrapper.node进行处理
RealWrapper = module.exports;
//先行获取LoginService操作权
loginService = new RealWrapper.NodeIKernelLoginService();
wrapperLoginService = loginService;
//开始针对性处理
module.exports = new Proxy({}, {
get: function (target, ServiceName, receiver) {
if (ServiceName == 'NodeIKernelLoginService') return CreateFuckService(ServiceName);
if (ServiceName == 'NodeIQQNTWrapperSession') return CreateFuckService(ServiceName);
return RealWrapper[ServiceName];
}
});
//返回预先构造的对象
return dlopenRet;
}; };
/** //辅助函数
* 清理 Hook
*/
function clearHook() { function clearHook() {
initCallBack = []; initCallBack = [];
process.dlopen = dlopenOrig; process.dlopen = dlopenOrig;
} }
function ntIsInitialized_Internal() { function ntIsInitialized_Internal() {
return wrapperSession !== undefined return wrapperSession !== undefined;
&& wrapperNodeApi !== undefined
&& wrapperLoginService !== undefined;
} }
function pollForNTInitializationCheck() { function pollForNTInitializationCheck() {
@ -111,7 +149,7 @@ async function fetchServices(timeout = 10000) {
setTimeout(() => resolve(false), timeout); setTimeout(() => resolve(false), timeout);
}), }),
]).then(result => result ? ]).then(result => result ?
{ wrapperSession, wrapperNodeApi, wrapperLoginService } : { wrapperSession, wrapperLoginService } :
Promise.reject("fetchServices Timeout!"), Promise.reject("fetchServices Timeout!"),
); );
} }

View File

@ -171,7 +171,7 @@ const _handlers: {
} else { } else {
postData = data; postData = data;
} }
// Mlikiowa V2.1.0 Refactor Todo // Mlikiowa V2.2.0 Refactor Todo
const signUrl = obContext.configLoader.configData.musicSignUrl; const signUrl = obContext.configLoader.configData.musicSignUrl;
if (!signUrl) { if (!signUrl) {
if (data.type === 'qq') { if (data.type === 'qq') {

View File

@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
SettingItem( SettingItem(
'<span id="napcat-update-title">Napcat</span>', '<span id="napcat-update-title">Napcat</span>',
undefined, undefined,
SettingButton('V2.1.0', 'napcat-update-button', 'secondary'), SettingButton('V2.2.0', 'napcat-update-button', 'secondary'),
), ),
]), ]),
SettingList([ SettingList([

View File

@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
SettingItem( SettingItem(
'<span id="napcat-update-title">Napcat</span>', '<span id="napcat-update-title">Napcat</span>',
void 0, void 0,
SettingButton("V2.1.0", "napcat-update-button", "secondary") SettingButton("V2.2.0", "napcat-update-button", "secondary")
) )
]), ]),
SettingList([ SettingList([