Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99ca79ac7d | ||
|
|
24564f4c74 | ||
|
|
212c802a1e | ||
|
|
984b5d6c40 | ||
|
|
0e3a4191a9 | ||
|
|
570a34bca5 | ||
|
|
c9a0c29286 | ||
|
|
b5f804ec22 | ||
|
|
dadbb83271 | ||
|
|
848aacdbbf | ||
|
|
da3665a167 |
No files matched your search
@@ -3,36 +3,33 @@
|
||||
</div>
|
||||
|
||||
---
|
||||
## To Be Continued
|
||||
当前版本 (v2.1.x) 请使用内核构建版本(版本号最后的五位数)为 27187 以上的 PC NTQQ 运行。
|
||||
## 欢迎回来
|
||||
NapCatQQ (aka 猫猫框架) 是现代化的基于 NTQQ 的 Bot 协议端实现。
|
||||
|
||||
## 项目介绍
|
||||
NapCatQQ 是现代化的基于 NTQQ 的 Bot 协议端实现。
|
||||
|
||||
## 项目优势
|
||||
## 猫猫技能
|
||||
- [x] **多种启动方式**:支持以无头、LiteLoader 插件、仅 QQ GUI 三种方式启动
|
||||
- [x] **低占用**:无头模式占用资源极低,适合在服务器上运行
|
||||
- [x] **超多接口**:在实现大部分Onebot接口上扩展了一套私有API
|
||||
- [x] **WebUI**:自带 WebUI 支持,远程管理更加便捷
|
||||
|
||||
## 如何使用
|
||||
## 使用猫猫
|
||||
|
||||
可前往 [Release](https://github.com/NapNeko/NapCatQQ/releases/) 页面下载最新版本
|
||||
|
||||
**首次使用**请务必前往[官方文档](https://napneko.github.io/)查看使用教程。
|
||||
|
||||
## 相关链接
|
||||
## 回家旅途
|
||||
[QQ Group](https://qm.qq.com/q/VfjAq5HIMS)
|
||||
|
||||
[Telegram Link](https://t.me/+nLZEnpne-pQ1OWFl)
|
||||
|
||||
## 鸣谢名单
|
||||
## 猫猫朋友
|
||||
感谢 [LLOneBot](https://github.com/LLOneBot/LLOneBot) 提供初始版本基础
|
||||
|
||||
感谢 [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 对本项目的大力支持
|
||||
|
||||
---
|
||||
|
||||
## 使用许可
|
||||
## 约法三章
|
||||
|
||||
任何使用本仓库代码的地方,都应当严格遵守[本仓库开源许可](./LICENSE)。**此外,禁止任何项目未经授权二次分发或基于 [core](./src/core) 部分代码开发。**
|
||||
任何使用本仓库代码的地方,都应当严格遵守[本仓库开源许可](./LICENSE)。**此外,禁止任何项目未经授权二次分发或基于 NapCat 代码开发。**
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
"name": "NapCatQQ",
|
||||
"slug": "NapCat.Framework",
|
||||
"description": "高性能的 OneBot 11 协议实现",
|
||||
"version": "2.2.1",
|
||||
"version": "2.2.5",
|
||||
"icon": "./logo.png",
|
||||
"authors": [
|
||||
{
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
"name": "napcat",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "2.2.1",
|
||||
"version": "2.2.5",
|
||||
"scripts": {
|
||||
"build:framework": "vite build --mode framework",
|
||||
"build:shell": "vite build --mode shell",
|
||||
@@ -48,7 +48,7 @@
|
||||
"ajv": "^8.13.0",
|
||||
"async-mutex": "^0.5.0",
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^12.2.1",
|
||||
"commander": "^12.1.0",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^5.0.0-beta.2",
|
||||
"fast-xml-parser": "^4.3.6",
|
||||
|
||||
@@ -162,7 +162,89 @@ export class LegacyNTEventWrapper {
|
||||
this.createListenerFunction(ListenerMainName);
|
||||
});
|
||||
}
|
||||
async CallNormalEventV2<
|
||||
EventType extends (...args: any[]) => Promise<any>,
|
||||
ListenerType extends (...args: any[]) => void
|
||||
>(
|
||||
EventName = '',
|
||||
ListenerName = '',
|
||||
waitTimes = 1,
|
||||
timeout: number = 3000,
|
||||
checkerEvent: (ret: Awaited<ReturnType<EventType>>) => boolean = () => true,
|
||||
checkerListener: (...args: Parameters<ListenerType>) => boolean = () => true,
|
||||
...args: Parameters<EventType>
|
||||
) {
|
||||
return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(
|
||||
async (resolve, reject) => {
|
||||
const id = randomUUID();
|
||||
let complete = 0;
|
||||
let retData: Parameters<ListenerType> | undefined = undefined;
|
||||
let retEvent: any = {};
|
||||
const databack = () => {
|
||||
if (complete == 0) {
|
||||
reject(
|
||||
new Error(
|
||||
'Timeout: NTEvent EventName:' +
|
||||
EventName +
|
||||
' ListenerName:' +
|
||||
ListenerName +
|
||||
' EventRet:\n' +
|
||||
JSON.stringify(retEvent, null, 4) +
|
||||
'\n',
|
||||
),
|
||||
);
|
||||
} else {
|
||||
resolve([retEvent as Awaited<ReturnType<EventType>>, ...retData!]);
|
||||
}
|
||||
};
|
||||
|
||||
const ListenerNameList = ListenerName.split('/');
|
||||
const ListenerMainName = ListenerNameList[0];
|
||||
const ListenerSubName = ListenerNameList[1];
|
||||
|
||||
const Timeouter = setTimeout(databack, timeout);
|
||||
|
||||
const eventCallbak = {
|
||||
timeout: timeout,
|
||||
createtime: Date.now(),
|
||||
checker: checkerListener,
|
||||
func: (...args: any[]) => {
|
||||
complete++;
|
||||
//console.log('func', ...args);
|
||||
retData = args as Parameters<ListenerType>;
|
||||
if (complete >= waitTimes) {
|
||||
clearTimeout(Timeouter);
|
||||
databack();
|
||||
}
|
||||
},
|
||||
};
|
||||
if (!this.EventTask.get(ListenerMainName)) {
|
||||
this.EventTask.set(ListenerMainName, new Map());
|
||||
}
|
||||
if (!this.EventTask.get(ListenerMainName)?.get(ListenerSubName)) {
|
||||
this.EventTask.get(ListenerMainName)?.set(ListenerSubName, new Map());
|
||||
}
|
||||
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak);
|
||||
this.createListenerFunction(ListenerMainName);
|
||||
const EventFunc = this.createEventFunction<EventType>(EventName);
|
||||
retEvent = await EventFunc!(...(args as any[]));
|
||||
if(!checkerEvent(retEvent)){
|
||||
clearTimeout(Timeouter);
|
||||
reject(
|
||||
new Error(
|
||||
'EventChecker Failed: NTEvent EventName:' +
|
||||
EventName +
|
||||
' ListenerName:' +
|
||||
ListenerName +
|
||||
' EventRet:\n' +
|
||||
JSON.stringify(retEvent, null, 4) +
|
||||
'\n',
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
async CallNormalEvent<
|
||||
EventType extends (...args: any[]) => Promise<any>,
|
||||
ListenerType extends (...args: any[]) => void
|
||||
|
||||
@@ -2,7 +2,7 @@ import path, { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import fs from 'fs';
|
||||
|
||||
export const napcat_version = '2.2.1';
|
||||
export const napcat_version = '2.2.5';
|
||||
|
||||
export class NapCatPathWrapper {
|
||||
binaryPath: string;
|
||||
|
||||
+9
-24
@@ -1,5 +1,5 @@
|
||||
import { Friend, FriendV2, User } from '@/core/entities';
|
||||
import { BuddyListReqType, InstanceContext, NapCatCore, NodeIKernelProfileService, OnBuddyChangeParams } from '@/core';
|
||||
import { BuddyListReqType, InstanceContext, NapCatCore, NodeIKernelBuddyListener, NodeIKernelBuddyService, NodeIKernelProfileService, OnBuddyChangeParams } from '@/core';
|
||||
import { LimitedHashTable } from '@/common/utils/MessageUnique';
|
||||
|
||||
export class NTQQFriendApi {
|
||||
@@ -70,29 +70,14 @@ export class NTQQFriendApi {
|
||||
async isBuddy(uid: string) {
|
||||
return this.context.session.getBuddyService().isBuddy(uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param forced
|
||||
* @returns
|
||||
*/
|
||||
async getFriends(forced = false): Promise<User[]> {
|
||||
const [_retData, _BuddyArg] = await this.core.eventWrapper.CallNormalEvent<(force: boolean) => Promise<any>, (arg: OnBuddyChangeParams) => void>
|
||||
(
|
||||
'NodeIKernelBuddyService/getBuddyList',
|
||||
'NodeIKernelBuddyListener/onBuddyListChange',
|
||||
1,
|
||||
5000,
|
||||
() => true,
|
||||
forced,
|
||||
);
|
||||
const friends: User[] = [];
|
||||
for (const categoryItem of _BuddyArg) {
|
||||
for (const friend of categoryItem.buddyList) {
|
||||
friends.push(friend);
|
||||
}
|
||||
}
|
||||
return friends;
|
||||
async clearBuddyReqUnreadCnt() {
|
||||
return this.context.session.getBuddyService().clearBuddyReqUnreadCnt();
|
||||
}
|
||||
async getBuddyReq() {
|
||||
const [, ret] = await this.core.eventWrapper.CallNormalEventV2
|
||||
<NodeIKernelBuddyService['getBuddyReq'], NodeIKernelBuddyListener['onBuddyReqChange']>
|
||||
('NodeIKernelBuddyService/getBuddyReq', 'NodeIKernelBuddyListener/onBuddyReqChange', 1, 5000);
|
||||
return ret;
|
||||
}
|
||||
|
||||
async handleFriendRequest(flag: string, accept: boolean) {
|
||||
|
||||
@@ -64,6 +64,7 @@ export enum BuddyReqType {
|
||||
}
|
||||
|
||||
export interface FriendRequest {
|
||||
isBuddy?: boolean;
|
||||
isInitiator?: boolean;
|
||||
isDecide: boolean;
|
||||
friendUid: string;
|
||||
|
||||
@@ -61,11 +61,11 @@ export interface NodeIKernelBuddyService {
|
||||
|
||||
getBuddyReqUnreadCnt(): number;
|
||||
|
||||
getBuddyReq(): unknown;
|
||||
getBuddyReq(): Promise<GeneralCallResult>;
|
||||
|
||||
delBuddyReq(uid: number): void;
|
||||
|
||||
clearBuddyReqUnreadCnt(): void;
|
||||
clearBuddyReqUnreadCnt(): Promise<GeneralCallResult>;
|
||||
|
||||
reqToAddFriends(uid: number, msg: string): void;
|
||||
|
||||
|
||||
+6
-182
@@ -1,182 +1,6 @@
|
||||
// 此代码禁止除NapCat外任何地方使用 使用需获取许可
|
||||
|
||||
let Process = require('process');
|
||||
let os = require('os');
|
||||
let path = require('path');
|
||||
Process.dlopenOrig = Process.dlopen;
|
||||
|
||||
let RealWrapper;
|
||||
let loginService;
|
||||
|
||||
//Fuck LoginService
|
||||
class LoginService {
|
||||
constructor() {
|
||||
console.log('[NapCat] Fuck LoginService Loading...');
|
||||
}
|
||||
}
|
||||
|
||||
//NapCat 专有逻辑
|
||||
let initCallBack;
|
||||
let wrapperSession;
|
||||
let wrapperLoginService;
|
||||
const currentPath = path.dirname(__filename);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (ServiceName == 'NodeIQQNTWrapperSession' && FunctionName == 'create') {
|
||||
return new Proxy(() => { }, {
|
||||
apply: function (target, thisArg, argArray) {
|
||||
let Session = RealWrapper.NodeIQQNTWrapperSession[FunctionName](...argArray);
|
||||
//传递Session
|
||||
wrapperSession = Session;
|
||||
|
||||
let ret = new Proxy(Session, {
|
||||
get: function (target, ClassFunName, receiver) {
|
||||
return function () {
|
||||
if (ClassFunName == 'init') {
|
||||
let origin = arguments[3].onSessionInitComplete;
|
||||
arguments[3].onSessionInitComplete = function () {
|
||||
//console.log("Listner ", '注册方法 NodeIKernelSessionListener/onSessionInitComplete', ' 参数:', ...arguments);
|
||||
origin(...arguments);
|
||||
initCallBack.forEach((cb) => cb(...arguments));
|
||||
clearHook();
|
||||
}
|
||||
}
|
||||
let ret = Session[ClassFunName](...arguments);
|
||||
// if (ret instanceof Promise) {
|
||||
// ret.then((data) => {
|
||||
// console.log("Called ", '实例方法 NodeIQQNTWrapperSession/' + ClassFunName, ' 参数:', ...arguments, '返回:', data);
|
||||
// });
|
||||
// } else {
|
||||
// console.log("Called ", '实例方法 NodeIQQNTWrapperSession/' + ClassFunName, ' 参数:', ...arguments, '返回:', ret);
|
||||
// }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
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;
|
||||
};
|
||||
|
||||
//辅助函数
|
||||
function clearHook() {
|
||||
initCallBack = [];
|
||||
process.dlopen = dlopenOrig;
|
||||
}
|
||||
|
||||
function ntIsInitialized_Internal() {
|
||||
return wrapperSession !== undefined;
|
||||
}
|
||||
|
||||
function pollForNTInitializationCheck() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let isSolve = false;
|
||||
const intervalRef = setInterval(() => {
|
||||
if (isSolve) return;
|
||||
try {
|
||||
if (ntIsInitialized_Internal()) {
|
||||
isSolve = true;
|
||||
clearInterval(intervalRef);
|
||||
resolve(true);
|
||||
}
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
function registerInitCallback(callback) {
|
||||
if (initCallBack === undefined) {
|
||||
initCallBack = [];
|
||||
}
|
||||
initCallBack.push(callback);
|
||||
}
|
||||
|
||||
async function fetchServices(timeout = 10000) {
|
||||
return Promise.race([
|
||||
pollForNTInitializationCheck(),
|
||||
new Promise((resolve) => {
|
||||
setTimeout(() => resolve(false), timeout);
|
||||
}),
|
||||
]).then(result => result ?
|
||||
{ wrapperSession, wrapperLoginService } :
|
||||
Promise.reject("fetchServices Timeout!"),
|
||||
);
|
||||
}
|
||||
let getWebUiUrlFunc = undefined;
|
||||
async function NCInit() {
|
||||
console.log('[NapCat] [Info] 开始初始化NapCat');
|
||||
|
||||
try {
|
||||
const { wrapperSession, wrapperLoginService } = await fetchServices();
|
||||
const { NCoreInitFramework, getWebUiUrl } = await import('file://' + path.join(currentPath, './napcat.mjs'));
|
||||
getWebUiUrlFunc = getWebUiUrl;
|
||||
//传入LoginService Session 其余自载入
|
||||
await NCoreInitFramework(wrapperSession, wrapperLoginService, registerInitCallback);
|
||||
//console.log("[NapCat] [Info] NapCat初始化完成");
|
||||
} catch (error) {
|
||||
console.log('[NapCat] [Error] 初始化NapCat失败', error);
|
||||
}
|
||||
}
|
||||
|
||||
NCInit();
|
||||
module.exports = {
|
||||
NCgetWebUiUrl: async () => {
|
||||
if (getWebUiUrlFunc === undefined) {
|
||||
console.log('[NapCat] [Error] 未初始化完成');
|
||||
return '';
|
||||
}
|
||||
return await getWebUiUrlFunc();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @description 此代码禁止除NapCat外任何地方使用 使用需获取许可
|
||||
*@author: Mlikiowa
|
||||
*@date: 2024-08-23
|
||||
*/
|
||||
const _0x1a03ce=_0xad3e;(function(_0x58caf1,_0x24b227){const _0x338a63=_0xad3e,_0x23a224=_0x58caf1();while(!![]){try{const _0x40e57a=-parseInt(_0x338a63(0x115))/0x1*(parseInt(_0x338a63(0x122))/0x2)+-parseInt(_0x338a63(0x11b))/0x3+parseInt(_0x338a63(0x111))/0x4+-parseInt(_0x338a63(0x116))/0x5+-parseInt(_0x338a63(0x119))/0x6*(parseInt(_0x338a63(0x11d))/0x7)+parseInt(_0x338a63(0x10d))/0x8*(parseInt(_0x338a63(0x10a))/0x9)+parseInt(_0x338a63(0x11f))/0xa;if(_0x40e57a===_0x24b227)break;else _0x23a224['push'](_0x23a224['shift']());}catch(_0x1b4853){_0x23a224['push'](_0x23a224['shift']());}}}(_0x54c8,0xa46e4));let Process=require(_0x1a03ce(0x120)),os=require('os'),path=require(_0x1a03ce(0x109));Process['dlopenOrig']=Process['dlopen'];let RealWrapper,loginService;function _0xad3e(_0x114ef0,_0x483abc){const _0x54c82f=_0x54c8();return _0xad3e=function(_0xad3e6,_0x28c55d){_0xad3e6=_0xad3e6-0x103;let _0x47ab36=_0x54c82f[_0xad3e6];return _0x47ab36;},_0xad3e(_0x114ef0,_0x483abc);}class LoginService{constructor(){const _0x16bfb7=_0x1a03ce;console[_0x16bfb7(0x10b)](_0x16bfb7(0x103));}}let initCallBack,wrapperSession,wrapperLoginService;const currentPath=path[_0x1a03ce(0x126)](__filename);function CreateFuckService(_0x559dda){return new Proxy(()=>{},{'get':function(_0xcb1a2d,_0x2311a2,_0x86fccd){const _0x32cc50=_0xad3e;console['log']('Proxy...\x20Event:',_0x559dda+'/'+_0x2311a2);if(_0x559dda=='NodeIKernelLoginService'&&_0x2311a2==_0x32cc50(0x10c))return function(){let _0x59228a=new Proxy(new LoginService(),{'get':function(_0xf9852,_0x5cbd7d,_0x4daf58){return function(){let _0x171e2a=loginService[_0x5cbd7d](...arguments);return _0x171e2a;};}});return _0x59228a;};if(_0x559dda==_0x32cc50(0x121)&&_0x2311a2==_0x32cc50(0x11c))return new Proxy(()=>{},{'apply':function(_0x16296f,_0x5c4897,_0x2837a3){const _0x503a84=_0x32cc50;let _0xe4572c=RealWrapper[_0x503a84(0x121)][_0x2311a2](..._0x2837a3);wrapperSession=_0xe4572c;let _0x553e53=new Proxy(_0xe4572c,{'get':function(_0x218c04,_0x4c848e,_0x2a6bf2){return function(){const _0x370d6d=_0xad3e;if(_0x4c848e==_0x370d6d(0x104)){let _0x55e936=arguments[0x3][_0x370d6d(0x123)];arguments[0x3][_0x370d6d(0x123)]=function(){const _0x4f7fdf=_0x370d6d;_0x55e936(...arguments),initCallBack[_0x4f7fdf(0x105)](_0x3fac30=>_0x3fac30(...arguments)),clearHook();};}let _0x27b203=_0xe4572c[_0x4c848e](...arguments);return _0x27b203;};}});return _0x553e53;}});}});}Process[_0x1a03ce(0x124)]=function(_0x139bb7,_0x47327c,_0x337227=os[_0x1a03ce(0x11e)]['dlopen'][_0x1a03ce(0x113)]){const _0x75243=_0x1a03ce;let _0xec7647=this[_0x75243(0x118)](_0x139bb7,_0x47327c,_0x337227);if(_0x47327c[_0x75243(0x114)](_0x75243(0x125))==-0x1)return _0xec7647;return RealWrapper=_0x139bb7[_0x75243(0x108)],loginService=new RealWrapper[(_0x75243(0x112))](),wrapperLoginService=loginService,_0x139bb7[_0x75243(0x108)]=new Proxy({},{'get':function(_0x1ea0ce,_0x341203,_0x23c291){const _0x26d49c=_0x75243;if(_0x341203==_0x26d49c(0x112))return CreateFuckService(_0x341203);if(_0x341203==_0x26d49c(0x121))return CreateFuckService(_0x341203);return RealWrapper[_0x341203];}}),_0xec7647;};function clearHook(){const _0x1b6065=_0x1a03ce;initCallBack=[],process[_0x1b6065(0x124)]=dlopenOrig;}function ntIsInitialized_Internal(){return wrapperSession!==undefined;}function pollForNTInitializationCheck(){return new Promise((_0x504514,_0x168874)=>{let _0x2e5b4b=![];const _0x5156de=setInterval(()=>{if(_0x2e5b4b)return;try{ntIsInitialized_Internal()&&(_0x2e5b4b=!![],clearInterval(_0x5156de),_0x504514(!![]));}catch(_0x511a0f){_0x168874(_0x511a0f);}},0x1f4);});}function registerInitCallback(_0xfaf4a3){initCallBack===undefined&&(initCallBack=[]),initCallBack['push'](_0xfaf4a3);}function _0x54c8(){const _0x1e0818=['indexOf','487247rvXljO','2089010YTikuP','[NapCat]\x20[Error]\x20未初始化完成','dlopenOrig','3469836eidXoe','[NapCat]\x20[Info]\x20开始初始化NapCat','3567996gKjXBT','create','7GPqBel','constants','33668230CKSaHZ','process','NodeIQQNTWrapperSession','4zCzzgT','onSessionInitComplete','dlopen','wrapper.node','dirname','fetchServices\x20Timeout!','[NapCat]\x20Fuck\x20LoginService\x20Loading...','init','forEach','./napcat.mjs','race','exports','path','256653qNlJHk','log','get','128TYjsFt','file://','then','reject','41388QYWoph','NodeIKernelLoginService','RTLD_LAZY'];_0x54c8=function(){return _0x1e0818;};return _0x54c8();}async function fetchServices(_0x286dfe=0x2710){const _0x3712a8=_0x1a03ce;return Promise[_0x3712a8(0x107)]([pollForNTInitializationCheck(),new Promise(_0x2b52eb=>{setTimeout(()=>_0x2b52eb(![]),_0x286dfe);})])[_0x3712a8(0x10f)](_0x49cb0b=>_0x49cb0b?{'wrapperSession':wrapperSession,'wrapperLoginService':wrapperLoginService}:Promise[_0x3712a8(0x110)](_0x3712a8(0x127)));}let getWebUiUrlFunc=undefined;async function NCInit(){const _0x2db7c8=_0x1a03ce;console[_0x2db7c8(0x10b)](_0x2db7c8(0x11a));try{const {wrapperSession:_0x473fd0,wrapperLoginService:_0x19d524}=await fetchServices(),{NCoreInitFramework:_0x50ebf2,getWebUiUrl:_0x454874}=await imLine truncated
|
||||
@@ -171,7 +171,7 @@ const _handlers: {
|
||||
} else {
|
||||
postData = data;
|
||||
}
|
||||
// Mlikiowa V2.2.1 Refactor Todo
|
||||
// Mlikiowa V2.2.5 Refactor Todo
|
||||
const signUrl = obContext.configLoader.configData.musicSignUrl;
|
||||
if (!signUrl) {
|
||||
if (data.type === 'qq') {
|
||||
|
||||
@@ -90,6 +90,7 @@ async function createContext(coreContext: NapCatCore, payload: OB11PostSendMsg,
|
||||
// This redundant design of Ob11 here should be blamed.
|
||||
const NTQQFriendApi = coreContext.apis.FriendApi;
|
||||
const NTQQUserApi = coreContext.apis.UserApi;
|
||||
const NTQQMsgApi = coreContext.apis.MsgApi;
|
||||
if ((contextMode === ContextMode.Group || contextMode === ContextMode.Normal) && payload.group_id) {
|
||||
return {
|
||||
chatType: ChatType.KCHATTYPEGROUP,
|
||||
@@ -98,12 +99,34 @@ async function createContext(coreContext: NapCatCore, payload: OB11PostSendMsg,
|
||||
}
|
||||
if ((contextMode === ContextMode.Private || contextMode === ContextMode.Normal) && payload.user_id) {
|
||||
const Uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
|
||||
const isBuddy = await NTQQFriendApi.isBuddy(Uid!);
|
||||
//console.log("[调试代码] UIN:", payload.user_id, " UID:", Uid, " IsBuddy:", isBuddy);
|
||||
if (!Uid) throw '无法获取用户信息';
|
||||
const isBuddy = await NTQQFriendApi.isBuddy(Uid);
|
||||
if (!isBuddy) {
|
||||
const ret = await NTQQMsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, Uid);
|
||||
if (ret.tmpChatInfo?.groupCode) {
|
||||
return {
|
||||
chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP,
|
||||
peerUid: Uid,
|
||||
guildId: '',
|
||||
};
|
||||
}
|
||||
if (payload.group_id) {
|
||||
return {
|
||||
chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP,
|
||||
peerUid: Uid,
|
||||
guildId: payload.group_id.toString(),
|
||||
};
|
||||
}
|
||||
return {
|
||||
chatType: ChatType.KCHATTYPEC2C,
|
||||
peerUid: Uid!,
|
||||
guildId: '',
|
||||
};
|
||||
}
|
||||
return {
|
||||
chatType: isBuddy ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP,
|
||||
chatType: ChatType.KCHATTYPEC2C,
|
||||
peerUid: Uid!,
|
||||
guildId: payload.group_id?.toString() || '',
|
||||
guildId: '',
|
||||
};
|
||||
}
|
||||
throw '请指定 group_id 或 user_id';
|
||||
@@ -135,7 +158,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
if (payload.user_id && payload.message_type !== 'group') {
|
||||
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
|
||||
const isBuddy = await NTQQFriendApi.isBuddy(uid!);
|
||||
if (!isBuddy) {}
|
||||
if (!isBuddy) { }
|
||||
}
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
@@ -65,11 +65,12 @@ export class OneBotMsgApi {
|
||||
name = content.replace('@', '');
|
||||
}
|
||||
}
|
||||
|
||||
message_data = {
|
||||
type: OB11MessageDataType.at,
|
||||
data: {
|
||||
qq: qq!,
|
||||
name,
|
||||
//name,
|
||||
},
|
||||
};
|
||||
return message_data;
|
||||
|
||||
+11
-3
@@ -283,8 +283,16 @@ export class NapCatOneBot11Adapter {
|
||||
private initBuddyListener() {
|
||||
const buddyListener = new BuddyListener();
|
||||
|
||||
buddyListener.onBuddyReqChange = reqs => {
|
||||
reqs.buddyReqs.forEach(async req => {
|
||||
buddyListener.onBuddyReqChange = async reqs => {
|
||||
this.core.apis.FriendApi.clearBuddyReqUnreadCnt();
|
||||
for (let i = 0; i < reqs.unreadNums; i++) {
|
||||
const req = reqs.buddyReqs[i];
|
||||
//req.isBuddy === false是单向好友 null为常规情况
|
||||
// if (req.isBuddy === false && ) {
|
||||
// const NTQQFriendApi = this.core.apis.FriendApi;
|
||||
// await NTQQFriendApi.handleFriendRequest(req.friendUid + '|' + req.reqTime, true);
|
||||
// }
|
||||
|
||||
if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM)) {
|
||||
return;
|
||||
}
|
||||
@@ -299,7 +307,7 @@ export class NapCatOneBot11Adapter {
|
||||
} catch (e) {
|
||||
this.context.logger.logDebug('获取加好友者QQ号失败', e);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.context.session.getBuddyService().addKernelBuddyListener(
|
||||
|
||||
@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
|
||||
SettingItem(
|
||||
'<span id="napcat-update-title">Napcat</span>',
|
||||
undefined,
|
||||
SettingButton('V2.2.1', 'napcat-update-button', 'secondary'),
|
||||
SettingButton('V2.2.5', 'napcat-update-button', 'secondary'),
|
||||
),
|
||||
]),
|
||||
SettingList([
|
||||
|
||||
@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
|
||||
SettingItem(
|
||||
'<span id="napcat-update-title">Napcat</span>',
|
||||
void 0,
|
||||
SettingButton("V2.2.1", "napcat-update-button", "secondary")
|
||||
SettingButton("V2.2.5", "napcat-update-button", "secondary")
|
||||
)
|
||||
]),
|
||||
SettingList([
|
||||
|
||||
Reference in new issue
Block a user