本帖最后由 dehby1024 于 2024-11-14 15:57 编辑
NTQQ 开发框架,适用于自动化、机器人等场景的解决方案
实现原理:通过注入 JavaScript 代码至 NTQQ 的入口,劫持 wrapper.node 的 export 对象实现主动调用/被动监听,实现发送消息、监听消息等功能
特性
- 主动调用/被动监听:支持消息发送、消息监听等功能。
- 支持装饰器:使用 TypeScript 装饰器简化 Hook 操作。
注意事项
- 开发阶段:项目仍在开发中,功能可能会有变动
- 手动注入:本项目不提供注入方式,你需要自行实现。
- 代码编写能力:需要具备一定的开发能力(Node.js && TypeScript)
开发者提醒
- 欢迎大家提交Pull以及Issue建议参与协作开发
- 有更多的建议以及点子欢迎在A5官方群参与讨论
开发环境
命令
- dev --- 开发测试代码 仅运行
/dev/test.ts 代码
- build --- 编译项目
- clean --- 清理编译文件
- debug --- 接收调试日志
上手指南
1. 首先你得有node npm的基础环境
2. 安装 yarn 包管理工具 npm install yarn -g
3. 初始化项目依赖 yarn
4. 编译代码 yarn build
5. 编译后得到 ./dist 目录编译结果
6. 将 NTQQ 的代码入口引导至./dist/index.js
装饰器
@NTQQLoader.Constructor
-
功能
@NTQQLoader.Constructor 是一个 类装饰器,用于 Hook NTQQ 类实例的构造函数入口。通过这个装饰器,可以在 NTQQ 类实例化时,执行自定义逻辑,实现对类实例的构造过程进行拦截和处理。
-
参数
ConstructorName(可选): export 对象实例构造路径/自定义标识入口,默认为当前自定义处理类的类名
-
使用场景
1.用于自动 Hook/Attach 至自定义处理类通过 export 对象进行标准化 create/get 实例构造的NTQQ 类
@NTQQLoader.Constructor("NodeIQQNTWrapperSession.create")
class WrapperSession extends BaseClassProxy {}
2.支持非标准实例化:特别适合那些无法通过 export 顶层对象直接 create 或 get 实例的情况。例如,通过静态方法(如 NodeIQQNTWrapperSession.getMsgService )获取的实例
@NTQQLoader.Constructor() // default "Custom"
class Custom extends BaseClassProxy {}
-
使用要求
使该装饰器的类必须为BaseClassProxy 的子类
@NTQQLoader.MethodHook
-
功能
@NTQQLoader.MethodHook 是一个 方法装饰器,用于 Hook NTQQ 类的方法。在方法调用时拦截执行,提供 origin(原始函数)和 method(原始方法名)作为参数,使得开发者可以在调用前后执行自定义逻辑。
-
参数
MethodName(可选):指定需要 Hook 的原始方法名。如果不传递此参数,默认使用当前被装饰的方法名。
-
使用场景
1.拦截和增强方法功能:适用于在调用方法之前或之后进行日志记录、权限校验、参数处理等。
@NTQQLoader.Constructor() // // default "NTMsgService"
export class NTMsgService extends BaseClassProxy {
private static _instance = new NTMsgService();
public constructor() {
super();
}
public static getInstance() {
return this._instance;
}
@NTQQLoader.MethodHook()
public sendMsg(this: MethodThis<NTMsgService>, ...args: any[]) {
args[0].content = "Hello!";
return this.origin(...args);
}
}
2.当方法签名内使用本类This时,支持主动调用
@NTQQLoader.Constructor()
export class NTMsgService extends BaseClassProxy {
private static _instance = new NTMsgService();
public constructor() {
super();
}
public static getInstance() {
return this._instance;
}
public sendMsg(...args: any[]): any;
@NTQQLoader.MethodHook()
public sendMsg(this: MethodThis<NTMsgService>, ...args: any[]) {
if(CallerType.Manual === this.invokeType)
{
// 来自主动调用
return "恭喜你调用成功";
}
return this.origin(...args);
}
}
// 主动调用原始方法
NTMsgService.getInstance().sendMsg(......);
-
使用要求
依赖 @NTQQLoader.Constructor 装饰器:@NTQQLoader.MethodHook 装饰的方法所属类,必须使用 @NTQQLoader.Constructor 进行装饰,确保在类实例化时,Hook 机制能够正确生效。
@NTQQLoader.AttachClassWithArg
-
功能
@NTQQLoader.AttachClassWithArg 是一个方法装饰器,主要用于将类方法传入的指定参数实例对象绑定到自定义处理类上。适用于那些无法直接通过 export 顶层对象进行构造或 create/get 方法实例化的类或者某些用于添加回调事件对象的方法。
-
参数
target:用于绑定对象的BaseClassProxy 子类
indexOfArg:方法参数索引
-
使用场景
1.通过返回值进行非标准实例化处理:某些类无法通过 export 直接实例化,也没有标准的 create/get 方法。这类实例通常无法直接通过 @NTQQLoader.Constructor 进行拦截和 Hook,它们在一些类方法的返回值内,即可以使用该装饰器实现返回值自动绑定
2.@NTQQLoader.AttachClassWithArg 允许通过类方法的参数实例对象,自动绑定到指定的自定义处理类上,实现对实例的进一步 Hook 和控制。
@NTQQLoader.Constructor()
class NTMsgListener extends BaseClassProxy {
public constructor() {
super();
}
@NTQQLoader.MethodHook()
public onRecvMsg(this: MethodThis<NTMsgListener>, ...args: any[])....
}
@NTQQLoader.MethodHook()
@NTQQLoader.AttachClass(NTMsgListener, 0) // indexOfArg:0
public addKernelMsgListener(this: MethodThis<NTMsgService>, listener:any) {
return this.origin(listener);
}
-
使用要求
与 @NTQQLoader.MethodHook 联合使用:通常需要结合 @NTQQLoader.MethodHook ,在方法级别进行拦截,并对目标实例对象进行处理。
@NTQQLoader.AttachClassWithRet
-
功能
@NTQQLoader.AttachClassWithRet 是一个方法装饰器,主要用于将类方法返回的实例对象绑定到自定义处理类上。适用于那些无法直接通过 export 顶层对象进行构造或 create/get 方法实例化的类或者某些用于添加回调事件对象的方法。
-
参数
target:用于绑定对象的BaseClassProxy 子类
-
使用场景
1.通过参数进行非标准实例化处理:某些类无法通过 export 直接实例化,也没有标准的 create/get 方法。这类实例通常无法直接通过 @NTQQLoader.Constructor 进行拦截和 Hook,它们在一些类方法的参数内,即可以使用该装饰器实现通过参数自动绑定,同时不影响原本的MethodHook 执行流程
2.@NTQQLoader.AttachClassWithArg (AttachClass ) 允许通过类方法的参数实例对象,自动绑定到指定的自定义处理类上,实现对实例的进一步 Hook 和控制。
@NTQQLoader.Constructor("NodeIQQNTWrapperSession.create")
class WrapperSession extends BaseClassProxy {
@NTQQLoader.MethodHook()
@NTQQLoader.AttachClassWithArg(NTMsgService) // 实例返回后自动附加至NTMsgService自定义处理类
public getMsgService(
this: MethodThis<WrapperSession>,
...args: any[]
) {
return this.origin(...args);
}
}
@NTQQLoader.Constructor() // default "NTMsgService"
export class NTMsgService extends BaseClassProxy {
// 必须是public
public constructor() {
super();
}
@NTQQLoader.MethodHook()
.....
}
-
使用要求
与 @NTQQLoader.MethodHook 联合使用:通常需要结合 @NTQQLoader.MethodHook ,在方法级别进行拦截,并对目标实例对象进行处理。
版权声明
该项目签署了 AGPL-3 授权许可,详情请参阅 LICENSE
|