mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
44 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fd7d2dbf53 | ||
![]() |
6609697752 | ||
![]() |
dcd6e1973e | ||
![]() |
3614a6e932 | ||
![]() |
931a0210e5 | ||
![]() |
f9e7de4b42 | ||
![]() |
8e0b79594e | ||
![]() |
17122c4360 | ||
![]() |
154f7b6a30 | ||
![]() |
52e5543d0b | ||
![]() |
3c304bd2ae | ||
![]() |
26609bb8fd | ||
![]() |
de3fa9aaa4 | ||
![]() |
788665f84c | ||
![]() |
3943782971 | ||
![]() |
8f899c40f2 | ||
![]() |
a1f582399e | ||
![]() |
440b63f662 | ||
![]() |
7d2cc3b56b | ||
![]() |
5fe3422469 | ||
![]() |
6c02cedb1e | ||
![]() |
3cc2f1dcad | ||
![]() |
773cdc5877 | ||
![]() |
361a7329d7 | ||
![]() |
29910f1236 | ||
![]() |
4a164016f5 | ||
![]() |
cebd3e62a4 | ||
![]() |
2562a38fa1 | ||
![]() |
d46c922bbf | ||
![]() |
66b59982f7 | ||
![]() |
ad397ccf7f | ||
![]() |
bdef80ede7 | ||
![]() |
385dcbc75a | ||
![]() |
74cf501c8f | ||
![]() |
0c200d6748 | ||
![]() |
e65a36c517 | ||
![]() |
126b54ad40 | ||
![]() |
78637751af | ||
![]() |
f96526ee3a | ||
![]() |
b3c7a91f3d | ||
![]() |
b8daeef0c4 | ||
![]() |
2b662944cf | ||
![]() |
3d516df01e | ||
![]() |
26b4a9b15b |
@@ -1,32 +0,0 @@
|
|||||||
# v1.6.8
|
|
||||||
|
|
||||||
QQ Version: Windows 9.9.12-26000 / Linux 3.2.9-26000
|
|
||||||
## 使用前警告
|
|
||||||
1. 在最近版本由于QQ本体大幅变动,为了保证NapCat可用性,NapCat近期启动与安装方式将将大幅变动,请关注文档和社群获取。
|
|
||||||
2. 在Core上完全执行开源,请不要用于违法用途,如此可能造成NapCat完全停止更新。
|
|
||||||
3. 针对原启动方式的围堵,NapCat研发了多种方式,除此其余理论与扩展的分析和思路将部分展示于Docs,以便各位参与开发与维护NapCat。
|
|
||||||
## 其余·备注
|
|
||||||
启动方式: WayBoot.03 (Electron Main进程为Node 直接注入代码 同理项目: LiteLoader)
|
|
||||||
|
|
||||||
## 修复与优化
|
|
||||||
1. 移除数据库文件读写 ~ 优化性能
|
|
||||||
2. 重构消息发送 极限速度优化 ~ 优化性能
|
|
||||||
3. WebUi配置热重载优化 ~ 修复问题
|
|
||||||
4. 修复偶现崩溃问题 ~ 修复问题
|
|
||||||
5. 修复群邀请通知事件多次推送问题 ~ 修复问题
|
|
||||||
6. 尝试修复因缓存引起的字段不全问题 ~ 修复问题
|
|
||||||
7. 修复在非常非常高并发的情况 上报自身消息 回复回错问题 ~ 修复问题
|
|
||||||
8. 修复图片SubType字段位置错误问题 ~ 修复问题
|
|
||||||
9. 修复Uid/Uin转换问题 ~ 修复问题
|
|
||||||
|
|
||||||
## 新增与调整
|
|
||||||
1. 最后发言时间重构 入群时间失效 ~ 替换功能
|
|
||||||
2. 重构文件发送/获取 ~ 优化性能
|
|
||||||
3. 支持GOCQ私聊上传接口 ~ 新增功能
|
|
||||||
4. 悄悄告诉你ws http可以同一个端口 ~ 新增功能
|
|
||||||
5. 根据config目录的默认配置初始化新的配置文件 ~ 新增功能
|
|
||||||
6. WebUi可以部署在nginx代理二级目录 配置端口设置为0可关闭WebUi ~ 新增功能
|
|
||||||
7. 新增收藏表情拉取接口 ~ 新增功能
|
|
||||||
8. 新增群头像设置接口 ~ 新增功能
|
|
||||||
|
|
||||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
|
11
docs/changelogs/CHANGELOG.v1.7.5.md
Normal file
11
docs/changelogs/CHANGELOG.v1.7.5.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# v1.7.5
|
||||||
|
|
||||||
|
QQ Version: Windows 9.9.15-26702 / Linux 3.2.12-26702
|
||||||
|
|
||||||
|
## 启动的方式
|
||||||
|
Way03/Way05
|
||||||
|
|
||||||
|
## 新增与调整
|
||||||
|
1. 支持 9.9.15/3.2.12 版本QQ
|
||||||
|
|
||||||
|
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
@@ -2,7 +2,7 @@
|
|||||||
"name": "napcat",
|
"name": "napcat",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "1.7.2",
|
"version": "1.7.5",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"watch:dev": "vite --mode development",
|
"watch:dev": "vite --mode development",
|
||||||
"watch:prod": "vite --mode production",
|
"watch:prod": "vite --mode production",
|
||||||
|
@@ -150,7 +150,7 @@ export class NTEventWrapper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>
|
async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>
|
||||||
(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, checker: (...args: Parameters<ListenerType>) => boolean, ...args: Parameters<EventType>) {
|
(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, checker: (...args: Parameters<ListenerType>) => boolean, ...args: Parameters<EventType>) {
|
||||||
return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(async (resolve, reject) => {
|
return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(async (resolve, reject) => {
|
||||||
const id = randomUUID();
|
const id = randomUUID();
|
||||||
let complete = 0;
|
let complete = 0;
|
||||||
|
@@ -3,7 +3,6 @@ import fs from 'node:fs';
|
|||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import { systemPlatform } from '@/common/utils/system';
|
import { systemPlatform } from '@/common/utils/system';
|
||||||
import { logError } from '@/common/utils/log';
|
import { logError } from '@/common/utils/log';
|
||||||
|
|
||||||
export const exePath = process.execPath;
|
export const exePath = process.execPath;
|
||||||
|
|
||||||
export const pkgInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'package.json');
|
export const pkgInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'package.json');
|
||||||
@@ -38,16 +37,16 @@ type QQVersionConfigInfo = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let _qqVersionConfigInfo: QQVersionConfigInfo = {
|
let _qqVersionConfigInfo: QQVersionConfigInfo = {
|
||||||
'baseVersion': '9.9.12-25765',
|
'baseVersion': '9.9.15-26702',
|
||||||
'curVersion': '9.9.12-25765',
|
'curVersion': '9.9.15-26702',
|
||||||
'prevVersion': '',
|
'prevVersion': '',
|
||||||
'onErrorVersions': [],
|
'onErrorVersions': [],
|
||||||
'buildId': '25765'
|
'buildId': '26702'
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fs.existsSync(configVersionInfoPath)) {
|
if (fs.existsSync(configVersionInfoPath)) {
|
||||||
try {
|
try {
|
||||||
const _ =JSON.parse(fs.readFileSync(configVersionInfoPath).toString());
|
const _ = JSON.parse(fs.readFileSync(configVersionInfoPath).toString());
|
||||||
_qqVersionConfigInfo = Object.assign(_qqVersionConfigInfo, _);
|
_qqVersionConfigInfo = Object.assign(_qqVersionConfigInfo, _);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError('Load QQ version config info failed, Use default version', e);
|
logError('Load QQ version config info failed, Use default version', e);
|
||||||
@@ -68,8 +67,10 @@ export const qqPkgInfo: QQPkgInfo = JSON.parse(fs.readFileSync(pkgInfoPath).toSt
|
|||||||
// Linux
|
// Linux
|
||||||
// app_version: '3.2.9-25765',
|
// app_version: '3.2.9-25765',
|
||||||
// qua: 'V1_LNX_NQ_3.2.10_25765_GW_B',
|
// qua: 'V1_LNX_NQ_3.2.10_25765_GW_B',
|
||||||
|
export function requireMinNTQBuild(buildStr: string) {
|
||||||
let _appid: string = '537234702'; // 默认为 Windows 平台的 appid
|
return parseInt(qqVersionConfigInfo.buildId) >= parseInt(buildStr);
|
||||||
|
}
|
||||||
|
let _appid: string = '537237765'; // 默认为 Windows 平台的 appid
|
||||||
if (systemPlatform === 'linux') {
|
if (systemPlatform === 'linux') {
|
||||||
_appid = '537234773';
|
_appid = '537234773';
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,27 @@ import * as fsPromise from 'node:fs/promises';
|
|||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
|
//下面这个类是用于将uid+msgid合并的类
|
||||||
|
export class UUIDConverter {
|
||||||
|
static encode(highStr: string, lowStr: string): string {
|
||||||
|
const high = BigInt(highStr);
|
||||||
|
const low = BigInt(lowStr);
|
||||||
|
const highHex = high.toString(16).padStart(16, '0');
|
||||||
|
const lowHex = low.toString(16).padStart(16, '0');
|
||||||
|
const combinedHex = highHex + lowHex;
|
||||||
|
const uuid = `${combinedHex.substring(0, 8)}-${combinedHex.substring(8, 12)}-${combinedHex.substring(12, 16)}-${combinedHex.substring(16, 20)}-${combinedHex.substring(20)}`;
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
static decode(uuid: string): { high: string, low: string } {
|
||||||
|
const hex = uuid.replace(/-/g, '');
|
||||||
|
const high = BigInt('0x' + hex.substring(0, 16));
|
||||||
|
const low = BigInt('0x' + hex.substring(16));
|
||||||
|
return { high: high.toString(), low: low.toString() };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function sleep(ms: number): Promise<void> {
|
export function sleep(ms: number): Promise<void> {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
@@ -4,10 +4,10 @@ export async function checkVersion(): Promise<string> {
|
|||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const MirrorList =
|
const MirrorList =
|
||||||
[
|
[
|
||||||
|
'https://jsd.cdn.zzko.cn/gh/NapNeko/NapCatQQ@main/package.json',
|
||||||
'https://fastly.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json',
|
'https://fastly.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json',
|
||||||
'https://gcore.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json',
|
'https://gcore.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json',
|
||||||
'https://cdn.jsdelivr.us/gh/NapNeko/NapCatQQ@main/package.json',
|
'https://cdn.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json'
|
||||||
'https://jsd.cdn.zzko.cn/gh/NapNeko/NapCatQQ@main/package.json'
|
|
||||||
];
|
];
|
||||||
let version = undefined;
|
let version = undefined;
|
||||||
for (const url of MirrorList) {
|
for (const url of MirrorList) {
|
||||||
|
@@ -18,6 +18,7 @@ import { sessionConfig } from '@/core/sessionConfig';
|
|||||||
import { rkeyManager } from '../utils/rkey';
|
import { rkeyManager } from '../utils/rkey';
|
||||||
import { NTEventDispatch } from '@/common/utils/EventTask';
|
import { NTEventDispatch } from '@/common/utils/EventTask';
|
||||||
import { NodeIKernelSearchService } from '../services/NodeIKernelSearchService';
|
import { NodeIKernelSearchService } from '../services/NodeIKernelSearchService';
|
||||||
|
import { selfInfo } from '../data';
|
||||||
|
|
||||||
|
|
||||||
export class NTQQFileApi {
|
export class NTQQFileApi {
|
||||||
@@ -67,7 +68,9 @@ export class NTQQFileApi {
|
|||||||
ext
|
ext
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
static async downloadMediaByUuid() {
|
||||||
|
//napCatCore.session.getRichMediaService().downloadFileForFileUuid();
|
||||||
|
}
|
||||||
static async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) {
|
static async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) {
|
||||||
//logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force);
|
//logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force);
|
||||||
// 用于下载收到的消息中的图片等
|
// 用于下载收到的消息中的图片等
|
||||||
|
@@ -1,14 +1,13 @@
|
|||||||
import { ElementType, GetFileListParam, MessageElement, Peer, RawMessage, SendMessageElement, SendMsgElementConstructor } from '@/core/entities';
|
import { GetFileListParam, Peer, RawMessage, SendMessageElement, SendMsgElementConstructor } from '@/core/entities';
|
||||||
import { friends, groups, selfInfo } from '@/core/data';
|
import { friends, groups, selfInfo } from '@/core/data';
|
||||||
import { log, logError, logWarn } from '@/common/utils/log';
|
import { log, logWarn } from '@/common/utils/log';
|
||||||
import { sleep } from '@/common/utils/helper';
|
import { sleep } from '@/common/utils/helper';
|
||||||
import { napCatCore, NodeIKernelMsgService, NTQQUserApi } from '@/core';
|
import { napCatCore, NTQQUserApi } from '@/core';
|
||||||
import { NodeIKernelMsgListener, onGroupFileInfoUpdateParamType } from '@/core/listeners';
|
import { onGroupFileInfoUpdateParamType } from '@/core/listeners';
|
||||||
import { GeneralCallResult } from '@/core/services/common';
|
import { GeneralCallResult } from '@/core/services/common';
|
||||||
import { MessageUnique } from '../../../common/utils/MessageUnique';
|
import { MessageUnique } from '../../../common/utils/MessageUnique';
|
||||||
import { NTEventDispatch } from '@/common/utils/EventTask';
|
import { NTEventDispatch } from '@/common/utils/EventTask';
|
||||||
import { logNotice } from '@/onebot11/log';
|
import { requireMinNTQBuild } from '@/common/utils/QQBasicInfo';
|
||||||
let MsgSendMode = 2;
|
|
||||||
|
|
||||||
async function LoadMessageIdList(Peer: Peer, msgId: string) {
|
async function LoadMessageIdList(Peer: Peer, msgId: string) {
|
||||||
let msgList = await NTQQMsgApi.getMsgHistory(Peer, msgId, 50);
|
let msgList = await NTQQMsgApi.getMsgHistory(Peer, msgId, 50);
|
||||||
@@ -42,8 +41,10 @@ async function loadMessageUnique() {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
napCatCore.onLoginSuccess(async () => {
|
napCatCore.onLoginSuccess(async () => {
|
||||||
await sleep(100);
|
await sleep(100);
|
||||||
NTQQMsgApi.CheckSendMode().then().catch();
|
// NTQQMsgApi.CheckSendMode().then().catch();
|
||||||
loadMessageUnique().then().catch();
|
loadMessageUnique().then().catch();
|
||||||
|
//let data = await napCatCore.session.getMsgService().sendSsoCmdReqByContend("LightAppSvc.mini_app_growguard.ReportExecute","1124343");
|
||||||
|
//console.log(data);
|
||||||
});
|
});
|
||||||
}, 100);
|
}, 100);
|
||||||
//歇菜LocalMsg压根不写Db
|
//歇菜LocalMsg压根不写Db
|
||||||
@@ -64,26 +65,8 @@ setTimeout(() => {
|
|||||||
// ));
|
// ));
|
||||||
// console.log(await NTQQMsgApi.multiForwardMsg(peer, peer, [MsgId]));
|
// console.log(await NTQQMsgApi.multiForwardMsg(peer, peer, [MsgId]));
|
||||||
// }, 25000)
|
// }, 25000)
|
||||||
|
|
||||||
export class NTQQMsgApi {
|
export class NTQQMsgApi {
|
||||||
static async CheckSendMode() {
|
|
||||||
try {
|
|
||||||
NTQQMsgApi.sendMsgV2({ chatType: 1, peerUid: selfInfo.uid }, [SendMsgElementConstructor.text('消息队列模式测试')], true, 10000).then().catch();
|
|
||||||
MsgSendMode = 2;
|
|
||||||
logNotice('[消息队列] 消息模式确认: MsgId异步队列');
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
logNotice('[消息队列] 消息模式失败: MsgId异步队列');
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
NTQQMsgApi.sendMsgV1({ chatType: 1, peerUid: selfInfo.uid }, [SendMsgElementConstructor.text('消息队列模式测试')], true, 10000).then().catch();
|
|
||||||
MsgSendMode = 1;
|
|
||||||
logNotice('[消息队列] 消息模式确认: MsgSeq异步队列');
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
logNotice('[消息队列] 消息模式失败: MsgSeq异步队列');
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// static napCatCore: NapCatCore | null = null;
|
// static napCatCore: NapCatCore | null = null;
|
||||||
// enum BaseEmojiType {
|
// enum BaseEmojiType {
|
||||||
// NORMAL_EMOJI,
|
// NORMAL_EMOJI,
|
||||||
@@ -104,7 +87,7 @@ export class NTQQMsgApi {
|
|||||||
} | undefined> {
|
} | undefined> {
|
||||||
return napCatCore.session.getMsgService().getMultiMsg(peer, rootMsgId, parentMsgId);
|
return napCatCore.session.getMsgService().getMultiMsg(peer, rootMsgId, parentMsgId);
|
||||||
}
|
}
|
||||||
static async getLastestMsgByUids(peer: Peer) {
|
static async getLastestMsgByUids(peer: Peer, count: number = 20) {
|
||||||
let ret = await napCatCore.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', {
|
let ret = await napCatCore.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', {
|
||||||
chatInfo: peer,
|
chatInfo: peer,
|
||||||
filterMsgType: [],
|
filterMsgType: [],
|
||||||
@@ -141,9 +124,6 @@ export class NTQQMsgApi {
|
|||||||
}
|
}
|
||||||
static async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) {
|
static async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) {
|
||||||
return await napCatCore.session.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z);
|
return await napCatCore.session.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z);
|
||||||
}
|
|
||||||
static async testMode() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
static async setMsgRead(peer: Peer) {
|
static async setMsgRead(peer: Peer) {
|
||||||
return napCatCore.session.getMsgService().setMsgRead(peer);
|
return napCatCore.session.getMsgService().setMsgRead(peer);
|
||||||
@@ -153,7 +133,7 @@ export class NTQQMsgApi {
|
|||||||
(GroupCode: string, params: GetFileListParam) => Promise<unknown>,
|
(GroupCode: string, params: GetFileListParam) => Promise<unknown>,
|
||||||
(groupFileListResult: onGroupFileInfoUpdateParamType) => void
|
(groupFileListResult: onGroupFileInfoUpdateParamType) => void
|
||||||
>(
|
>(
|
||||||
'NodeIKernelRichMediaService/sendMsg',
|
'NodeIKernelRichMediaService/getGroupFileList',
|
||||||
'NodeIKernelMsgListener/onGroupFileInfoUpdate',
|
'NodeIKernelMsgListener/onGroupFileInfoUpdate',
|
||||||
1,
|
1,
|
||||||
5000,
|
5000,
|
||||||
@@ -185,7 +165,8 @@ export class NTQQMsgApi {
|
|||||||
// const msgId = BigInt("0x" + buffer.toString('hex')).toString();
|
// const msgId = BigInt("0x" + buffer.toString('hex')).toString();
|
||||||
// return msgId;
|
// return msgId;
|
||||||
// }
|
// }
|
||||||
let msgId = await NTQQMsgApi.getMsgUnique(await NTQQMsgApi.getServerTime());
|
|
||||||
|
let msgId = await NTQQMsgApi.getMsgUnique(peer.chatType, await NTQQMsgApi.getServerTime());
|
||||||
let data = await NTEventDispatch.CallNormalEvent<
|
let data = await NTEventDispatch.CallNormalEvent<
|
||||||
(msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>,
|
(msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>,
|
||||||
(msgList: RawMessage[]) => void
|
(msgList: RawMessage[]) => void
|
||||||
@@ -214,58 +195,47 @@ export class NTQQMsgApi {
|
|||||||
});
|
});
|
||||||
return retMsg;
|
return retMsg;
|
||||||
}
|
}
|
||||||
static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
|
static sendMsgEx(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
|
||||||
if (MsgSendMode == 1) {
|
//return NTQQMsgApi.sendMsgV1(peer, msgElements, waitComplete, timeout);
|
||||||
return NTQQMsgApi.sendMsgV1(peer, msgElements, waitComplete, timeout);
|
|
||||||
} else if (MsgSendMode == 2) {
|
|
||||||
return NTQQMsgApi.sendMsgV2(peer, msgElements, waitComplete, timeout);
|
|
||||||
}
|
|
||||||
throw new Error('未知的发送消息模式');
|
|
||||||
}
|
}
|
||||||
static async sendMsgV1(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
|
static async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
|
||||||
let msgList = await NTQQMsgApi.getLastestMsgByUids(peer);
|
//唉? !我有个想法
|
||||||
let msgCurrentSeq = 0n;
|
let msgId = await NTQQMsgApi.getMsgUnique(peer.chatType, await NTQQMsgApi.getServerTime());
|
||||||
if (msgList.msgList.length > 0) {
|
peer.guildId = msgId;
|
||||||
msgCurrentSeq = BigInt(msgList.msgList[0].msgSeq);
|
let data = await NTEventDispatch.CallNormalEvent<
|
||||||
}
|
(msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>,
|
||||||
let rawMsg: RawMessage | undefined;
|
(msgList: RawMessage[]) => void
|
||||||
let EventListener = NTEventDispatch.RegisterListen<NodeIKernelMsgListener['onAddSendMsg']>('NodeIKernelMsgListener/onAddSendMsg', 1, timeout, (msg: RawMessage) => {
|
>(
|
||||||
//console.log("msgSeq:", msgCurrentSeq.toString(), JSON.stringify(msgList.msgList[0], null, 4));
|
'NodeIKernelMsgService/sendMsg',
|
||||||
if (msg.peerUid == peer.peerUid && (msgCurrentSeq == 0n || msgList.msgList[0].msgSeq == msgCurrentSeq.toString())) {
|
'NodeIKernelMsgListener/onMsgInfoListUpdate',
|
||||||
rawMsg = msg;
|
1,
|
||||||
return true;
|
timeout,
|
||||||
}
|
(msgRecords: RawMessage[]) => {
|
||||||
return false;
|
for (let msgRecord of msgRecords) {
|
||||||
}).catch(logError);
|
if (msgRecord.guildId === msgId && msgRecord.sendStatus === 2) {
|
||||||
let EventListener2 = NTEventDispatch.RegisterListen<NodeIKernelMsgListener['onMsgInfoListUpdate']>('NodeIKernelMsgListener/onMsgInfoListUpdate', 1, timeout,
|
|
||||||
(msgList: RawMessage[]) => {
|
|
||||||
for (let msg of msgList) {
|
|
||||||
if (msg.peerUid == peer.peerUid && rawMsg && rawMsg.msgId == msg.msgId && msg.sendStatus == 2) {
|
|
||||||
rawMsg = msg;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}).catch(logError);
|
},
|
||||||
await NTEventDispatch.CallNoListenerEvent<NodeIKernelMsgService['sendMsg']>('NodeIKernelMsgService/sendMsg', timeout, "0", peer, msgElements, new Map());
|
"0",
|
||||||
await EventListener;
|
peer,
|
||||||
await EventListener2;
|
msgElements,
|
||||||
// console.log("rawMsg", JSON.stringify(rawMsg, null, 4));
|
new Map()
|
||||||
if (rawMsg) {
|
);
|
||||||
return rawMsg;
|
let retMsg = data[1].find(msgRecord => {
|
||||||
|
if (msgRecord.guildId === msgId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return retMsg;
|
||||||
|
}
|
||||||
|
static async getMsgUnique(chatType: number, time: string) {
|
||||||
|
if (requireMinNTQBuild('26702')) {
|
||||||
|
return napCatCore.session.getMsgService().generateMsgUniqueId(chatType, time);
|
||||||
}
|
}
|
||||||
throw new Error('发送消息超时');
|
|
||||||
}
|
|
||||||
static async getMsgUniqueEx() {
|
|
||||||
let msgId = await NTQQMsgApi.getMsgUnique(await NTQQMsgApi.getServerTime());
|
|
||||||
return msgId;
|
|
||||||
}
|
|
||||||
static async getMsgUnique(time: string) {
|
|
||||||
return napCatCore.session.getMsgService().getMsgUniqueId(time);
|
return napCatCore.session.getMsgService().getMsgUniqueId(time);
|
||||||
}
|
}
|
||||||
static async getMsgUniqueByTimeV2() {
|
|
||||||
return NTEventDispatch.CallNoListenerEvent<NodeIKernelMsgService['getMsgUniqueId']>('NodeIKernelMsgService/getMsgUniqueId', 5000, await NTQQMsgApi.getServerTimeV2())
|
|
||||||
}
|
|
||||||
static async getServerTime() {
|
static async getServerTime() {
|
||||||
return napCatCore.session.getMSFService().getServerTime();
|
return napCatCore.session.getMSFService().getServerTime();
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,8 @@ import { NodeIKernelProfileListener, ProfileListener } from '@/core/listeners';
|
|||||||
import { RequestUtil } from '@/common/utils/request';
|
import { RequestUtil } from '@/common/utils/request';
|
||||||
import { logWarn } from '@/common/utils/log';
|
import { logWarn } from '@/common/utils/log';
|
||||||
import { NTEventDispatch } from '@/common/utils/EventTask';
|
import { NTEventDispatch } from '@/common/utils/EventTask';
|
||||||
import { NodeIKernelProfileService } from '@/core/services';
|
import { NodeIKernelProfileService, ProfileBizType, UserDetailSource } from '@/core/services';
|
||||||
|
import { requireMinNTQBuild } from '@/common/utils/QQBasicInfo';
|
||||||
|
|
||||||
export class NTQQUserApi {
|
export class NTQQUserApi {
|
||||||
static async getProfileLike(uid: string) {
|
static async getProfileLike(uid: string) {
|
||||||
@@ -64,7 +65,49 @@ export class NTQQUserApi {
|
|||||||
// KQZONE,
|
// KQZONE,
|
||||||
// KOTHER
|
// KOTHER
|
||||||
// }
|
// }
|
||||||
|
static async fetchUserDetailInfo(uid: string) {
|
||||||
|
type EventService = NodeIKernelProfileService['fetchUserDetailInfo'];
|
||||||
|
type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged'];
|
||||||
|
let [_retData, profile] = await NTEventDispatch.CallNormalEvent
|
||||||
|
<EventService, EventListener>
|
||||||
|
(
|
||||||
|
'NodeIKernelProfileService/fetchUserDetailInfo',
|
||||||
|
'NodeIKernelProfileListener/onUserDetailInfoChanged',
|
||||||
|
1,
|
||||||
|
5000,
|
||||||
|
(profile) => {
|
||||||
|
if (profile.uid === uid) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
"BuddyProfileStore",
|
||||||
|
[
|
||||||
|
uid
|
||||||
|
],
|
||||||
|
UserDetailSource.KSERVER,
|
||||||
|
[
|
||||||
|
ProfileBizType.KALL
|
||||||
|
]
|
||||||
|
);
|
||||||
|
let RetUser: User = {
|
||||||
|
...profile.simpleInfo.coreInfo,
|
||||||
|
...profile.simpleInfo.status,
|
||||||
|
...profile.simpleInfo.vasInfo,
|
||||||
|
...profile.commonExt,
|
||||||
|
...profile.simpleInfo.baseInfo,
|
||||||
|
qqLevel: profile.commonExt.qqLevel,
|
||||||
|
pendantId: ""
|
||||||
|
};
|
||||||
|
return RetUser;
|
||||||
|
}
|
||||||
static async getUserDetailInfo(uid: string) {
|
static async getUserDetailInfo(uid: string) {
|
||||||
|
if (requireMinNTQBuild('26702')) {
|
||||||
|
return this.fetchUserDetailInfo(uid);
|
||||||
|
}
|
||||||
|
return this.getUserDetailInfoOld(uid);
|
||||||
|
}
|
||||||
|
static async getUserDetailInfoOld(uid: string) {
|
||||||
type EventService = NodeIKernelProfileService['getUserDetailInfoWithBizInfo'];
|
type EventService = NodeIKernelProfileService['getUserDetailInfoWithBizInfo'];
|
||||||
type EventListener = NodeIKernelProfileListener['onProfileDetailInfoChanged'];
|
type EventListener = NodeIKernelProfileListener['onProfileDetailInfoChanged'];
|
||||||
let [_retData, profile] = await NTEventDispatch.CallNormalEvent
|
let [_retData, profile] = await NTEventDispatch.CallNormalEvent
|
||||||
|
@@ -731,6 +731,7 @@ export interface MultiForwardMsgElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface RawMessage {
|
export interface RawMessage {
|
||||||
|
guildId: string;
|
||||||
msgRandom: string;
|
msgRandom: string;
|
||||||
// int32, 自己维护的消息id
|
// int32, 自己维护的消息id
|
||||||
id?: number;
|
id?: number;
|
||||||
|
@@ -62,6 +62,7 @@ export enum BuddyReqType {
|
|||||||
KMEINITIATORWAITPEERCONFIRM
|
KMEINITIATORWAITPEERCONFIRM
|
||||||
}
|
}
|
||||||
export interface FriendRequest {
|
export interface FriendRequest {
|
||||||
|
isInitiator?: boolean;
|
||||||
isDecide: boolean;
|
isDecide: boolean;
|
||||||
friendUid: string;
|
friendUid: string;
|
||||||
reqType: BuddyReqType,
|
reqType: BuddyReqType,
|
||||||
|
@@ -9,7 +9,178 @@ export interface BuddyCategoryType {
|
|||||||
categroyMbCount: number;
|
categroyMbCount: number;
|
||||||
buddyList: User[];
|
buddyList: User[];
|
||||||
}
|
}
|
||||||
|
interface CoreInfo {
|
||||||
|
uid: string;
|
||||||
|
uin: string;
|
||||||
|
nick: string;
|
||||||
|
remark: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BaseInfo {
|
||||||
|
qid: string;
|
||||||
|
longNick: string;
|
||||||
|
birthday_year: number;
|
||||||
|
birthday_month: number;
|
||||||
|
birthday_day: number;
|
||||||
|
age: number;
|
||||||
|
sex: number;
|
||||||
|
eMail: string;
|
||||||
|
phoneNum: string;
|
||||||
|
categoryId: number;
|
||||||
|
richTime: number;
|
||||||
|
richBuffer: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MusicInfo {
|
||||||
|
buf: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VideoBizInfo {
|
||||||
|
cid: string;
|
||||||
|
tvUrl: string;
|
||||||
|
synchType: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VideoInfo {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExtOnlineBusinessInfo {
|
||||||
|
buf: string;
|
||||||
|
customStatus: any;
|
||||||
|
videoBizInfo: VideoBizInfo;
|
||||||
|
videoInfo: VideoInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExtBuffer {
|
||||||
|
buf: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UserStatus {
|
||||||
|
uid: string;
|
||||||
|
uin: string;
|
||||||
|
status: number;
|
||||||
|
extStatus: number;
|
||||||
|
batteryStatus: number;
|
||||||
|
termType: number;
|
||||||
|
netType: number;
|
||||||
|
iconType: number;
|
||||||
|
customStatus: any;
|
||||||
|
setTime: string;
|
||||||
|
specialFlag: number;
|
||||||
|
abiFlag: number;
|
||||||
|
eNetworkType: number;
|
||||||
|
showName: string;
|
||||||
|
termDesc: string;
|
||||||
|
musicInfo: MusicInfo;
|
||||||
|
extOnlineBusinessInfo: ExtOnlineBusinessInfo;
|
||||||
|
extBuffer: ExtBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PrivilegeIcon {
|
||||||
|
jumpUrl: string;
|
||||||
|
openIconList: any[];
|
||||||
|
closeIconList: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VasInfo {
|
||||||
|
vipFlag: boolean;
|
||||||
|
yearVipFlag: boolean;
|
||||||
|
svipFlag: boolean;
|
||||||
|
vipLevel: number;
|
||||||
|
bigClub: boolean;
|
||||||
|
bigClubLevel: number;
|
||||||
|
nameplateVipType: number;
|
||||||
|
grayNameplateFlag: number;
|
||||||
|
superVipTemplateId: number;
|
||||||
|
diyFontId: number;
|
||||||
|
pendantId: number;
|
||||||
|
pendantDiyId: number;
|
||||||
|
faceId: number;
|
||||||
|
vipFont: number;
|
||||||
|
vipFontType: number;
|
||||||
|
magicFont: number;
|
||||||
|
fontEffect: number;
|
||||||
|
newLoverDiamondFlag: number;
|
||||||
|
extendNameplateId: number;
|
||||||
|
diyNameplateIDs: any[];
|
||||||
|
vipStartFlag: number;
|
||||||
|
vipDataFlag: number;
|
||||||
|
gameNameplateId: string;
|
||||||
|
gameLastLoginTime: string;
|
||||||
|
gameRank: number;
|
||||||
|
gameIconShowFlag: boolean;
|
||||||
|
gameCardId: string;
|
||||||
|
vipNameColorId: string;
|
||||||
|
privilegeIcon: PrivilegeIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RelationFlags {
|
||||||
|
topTime: string;
|
||||||
|
isBlock: boolean;
|
||||||
|
isMsgDisturb: boolean;
|
||||||
|
isSpecialCareOpen: boolean;
|
||||||
|
isSpecialCareZone: boolean;
|
||||||
|
ringId: string;
|
||||||
|
isBlocked: boolean;
|
||||||
|
recommendImgFlag: number;
|
||||||
|
disableEmojiShortCuts: number;
|
||||||
|
qidianMasterFlag: number;
|
||||||
|
qidianCrewFlag: number;
|
||||||
|
qidianCrewFlag2: number;
|
||||||
|
isHideQQLevel: number;
|
||||||
|
isHidePrivilegeIcon: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface CommonExt {
|
||||||
|
constellation: number;
|
||||||
|
shengXiao: number;
|
||||||
|
kBloodType: number;
|
||||||
|
homeTown: string;
|
||||||
|
makeFriendCareer: number;
|
||||||
|
pos: string;
|
||||||
|
college: string;
|
||||||
|
country: string;
|
||||||
|
province: string;
|
||||||
|
city: string;
|
||||||
|
postCode: string;
|
||||||
|
address: string;
|
||||||
|
regTime: number;
|
||||||
|
interest: string;
|
||||||
|
labels: any[];
|
||||||
|
qqLevel: QQLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Pic {
|
||||||
|
picId: string;
|
||||||
|
picTime: number;
|
||||||
|
picUrlMap: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PhotoWall {
|
||||||
|
picList: Pic[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SimpleInfo {
|
||||||
|
uid: string;
|
||||||
|
uin: string;
|
||||||
|
coreInfo: CoreInfo;
|
||||||
|
baseInfo: BaseInfo;
|
||||||
|
status: UserStatus;
|
||||||
|
vasInfo: VasInfo;
|
||||||
|
relationFlags: RelationFlags;
|
||||||
|
otherFlags: any;
|
||||||
|
intimate: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserDetailInfoListenerArg {
|
||||||
|
uid: string;
|
||||||
|
uin: string;
|
||||||
|
simpleInfo: SimpleInfo;
|
||||||
|
commonExt: CommonExt;
|
||||||
|
photoWall: PhotoWall;
|
||||||
|
}
|
||||||
export interface ModifyProfileParams {
|
export interface ModifyProfileParams {
|
||||||
nick: string,
|
nick: string,
|
||||||
longNick: string,
|
longNick: string,
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import { User } from '@/core/entities';
|
import { User, UserDetailInfoListenerArg } from '@/core/entities';
|
||||||
|
|
||||||
interface IProfileListener {
|
interface IProfileListener {
|
||||||
onProfileSimpleChanged(...args: unknown[]): void;
|
onProfileSimpleChanged(...args: unknown[]): void;
|
||||||
|
onUserDetailInfoChanged(arg: UserDetailInfoListenerArg): void;
|
||||||
onProfileDetailInfoChanged(profile: User): void;
|
onProfileDetailInfoChanged(profile: User): void;
|
||||||
|
|
||||||
onStatusUpdate(...args: unknown[]): void;
|
onStatusUpdate(...args: unknown[]): void;
|
||||||
@@ -18,6 +18,9 @@ export interface NodeIKernelProfileListener extends IProfileListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ProfileListener implements IProfileListener {
|
export class ProfileListener implements IProfileListener {
|
||||||
|
onUserDetailInfoChanged(arg: UserDetailInfoListenerArg): void {
|
||||||
|
|
||||||
|
}
|
||||||
onProfileSimpleChanged(...args: unknown[]) {
|
onProfileSimpleChanged(...args: unknown[]) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,19 +1,35 @@
|
|||||||
import { Friend } from '@/core/entities';
|
import { Friend } from '@/core/entities';
|
||||||
import { GeneralCallResult } from '@/core/services/common';
|
import { GeneralCallResult } from '@/core/services/common';
|
||||||
import { NodeIKernelBuddyListener } from '@/core/listeners';
|
import { NodeIKernelBuddyListener } from '@/core/listeners';
|
||||||
|
export enum BuddyListReqType {
|
||||||
|
KNOMAL,
|
||||||
|
KLETTER
|
||||||
|
}
|
||||||
export interface NodeIKernelBuddyService {
|
export interface NodeIKernelBuddyService {
|
||||||
// 以下为自行添加的,wrapper.node中并没有这些方法,目的是简化调用
|
// 26702 以上
|
||||||
friends: Friend[];
|
getBuddyListV2(callFrom: string, reqType: BuddyListReqType): Promise<GeneralCallResult>;
|
||||||
|
//26702 以上
|
||||||
getFriend(uidOrUin: string): Promise<Friend>;
|
getBuddyListFromCache(callFrom: string): Promise<Array<
|
||||||
|
{
|
||||||
|
categoryId: number,//9999应该跳过 那是兜底数据吧
|
||||||
|
categorySortId: number,//排序方式
|
||||||
|
categroyName: string,//分类名
|
||||||
|
categroyMbCount: number,//不懂
|
||||||
|
onlineCount: number,//在线数目
|
||||||
|
buddyUids: Array<string>//Uids
|
||||||
|
}>>;
|
||||||
// 以下为原生方法
|
// 以下为原生方法
|
||||||
addKernelBuddyListener(listener: NodeIKernelBuddyListener): number;
|
addKernelBuddyListener(listener: NodeIKernelBuddyListener): number;
|
||||||
|
|
||||||
|
getAllBuddyCount(): number;
|
||||||
|
|
||||||
removeKernelBuddyListener(listener: unknown): void;
|
removeKernelBuddyListener(listener: unknown): void;
|
||||||
|
|
||||||
getBuddyList(bool: boolean): Promise<GeneralCallResult>;
|
/**
|
||||||
|
* @deprecated
|
||||||
|
* @param nocache 使用缓存
|
||||||
|
*/
|
||||||
|
getBuddyList(nocache: boolean): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
getBuddyNick(uid: number): string;
|
getBuddyNick(uid: number): string;
|
||||||
|
|
||||||
|
3
src/core/src/services/NodeIKernelECDHService.ts
Normal file
3
src/core/src/services/NodeIKernelECDHService.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export interface NodeIKernelECDHService{
|
||||||
|
|
||||||
|
}
|
@@ -9,7 +9,44 @@ import {
|
|||||||
import { GeneralCallResult } from '@/core/services/common';
|
import { GeneralCallResult } from '@/core/services/common';
|
||||||
|
|
||||||
export interface NodeIKernelGroupService {
|
export interface NodeIKernelGroupService {
|
||||||
setHeader(uid:string,path:string): unknown;
|
getGroupMemberLevelInfo(groupCode: string): Promise<unknown>;
|
||||||
|
//26702
|
||||||
|
getGroupHonorList(groupCodes: Array<string>): unknown;
|
||||||
|
getUinByUids(uins: string[]): Promise<unknown>;
|
||||||
|
getUidByUins(uins: string[]): Promise<unknown>;
|
||||||
|
//26702(其实更早 但是我不知道)
|
||||||
|
checkGroupMemberCache(arrayList: Array<string>): Promise<unknown>;
|
||||||
|
//26702(其实更早 但是我不知道)
|
||||||
|
getGroupLatestEssenceList(groupCode: string): Promise<unknown>;
|
||||||
|
//26702(其实更早 但是我不知道)
|
||||||
|
shareDigest(Req: {
|
||||||
|
appId: string,
|
||||||
|
appType: number,
|
||||||
|
msgStyle: number,
|
||||||
|
recvUin: string,
|
||||||
|
sendType: number,
|
||||||
|
clientInfo: {
|
||||||
|
platform: number
|
||||||
|
},
|
||||||
|
richMsg: {
|
||||||
|
usingArk: boolean,
|
||||||
|
title: string,
|
||||||
|
summary: string,
|
||||||
|
url: string,
|
||||||
|
pictureUrl: string,
|
||||||
|
brief: string
|
||||||
|
}
|
||||||
|
}): Promise<unknown>;
|
||||||
|
//26702(其实更早 但是我不知道)
|
||||||
|
isEssenceMsg(Req: { groupCode: string, msgRandom: number, msgSeq: number }): Promise<unknown>;
|
||||||
|
//26702(其实更早 但是我不知道)
|
||||||
|
queryCachedEssenceMsg(Req: { groupCode: string, msgRandom: number, msgSeq: number }): Promise<unknown>;
|
||||||
|
//26702(其实更早 但是我不知道)
|
||||||
|
fetchGroupEssenceList(Req: { groupCode: string, pageStart: number, pageLimit: number }, Arg: unknown): Promise<unknown>;
|
||||||
|
//26702
|
||||||
|
getAllMemberList(groupCode: string, refresh: boolean): Promise<unknown>;
|
||||||
|
|
||||||
|
setHeader(uid: string, path: string): unknown;
|
||||||
|
|
||||||
addKernelGroupListener(listener: NodeIKernelGroupListener): number;
|
addKernelGroupListener(listener: NodeIKernelGroupListener): number;
|
||||||
|
|
||||||
@@ -39,7 +76,7 @@ export interface NodeIKernelGroupService {
|
|||||||
|
|
||||||
modifyMemberCardName(groupCode: string, uid: string, cardName: string): void;
|
modifyMemberCardName(groupCode: string, uid: string, cardName: string): void;
|
||||||
|
|
||||||
getTransferableMemberInfo(uid: string): unknown;
|
getTransferableMemberInfo(groupCode: string): unknown;//获取整个群的
|
||||||
|
|
||||||
transferGroup(uid: string): void;
|
transferGroup(uid: string): void;
|
||||||
|
|
||||||
|
@@ -2,10 +2,23 @@ import { ElementType, MessageElement, Peer, RawMessage, SendMessageElement } fro
|
|||||||
import { NodeIKernelMsgListener } from '@/core/listeners/NodeIKernelMsgListener';
|
import { NodeIKernelMsgListener } from '@/core/listeners/NodeIKernelMsgListener';
|
||||||
import { GeneralCallResult } from '@/core/services/common';
|
import { GeneralCallResult } from '@/core/services/common';
|
||||||
|
|
||||||
|
export interface QueryMsgsParams {
|
||||||
|
chatInfo: Peer,
|
||||||
|
filterMsgType: [],
|
||||||
|
filterSendersUid: [],
|
||||||
|
filterMsgFromTime: string,
|
||||||
|
filterMsgToTime: string,
|
||||||
|
pageLimit: number,
|
||||||
|
isReverseOrder: boolean,
|
||||||
|
isIncludeCurrent: boolean
|
||||||
|
}
|
||||||
export interface NodeIKernelMsgService {
|
export interface NodeIKernelMsgService {
|
||||||
|
|
||||||
|
generateMsgUniqueId(chatType: number, time: string): string;
|
||||||
|
|
||||||
addKernelMsgListener(nodeIKernelMsgListener: NodeIKernelMsgListener): number;
|
addKernelMsgListener(nodeIKernelMsgListener: NodeIKernelMsgListener): number;
|
||||||
|
|
||||||
sendMsg(msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>): Promise<unknown>;
|
sendMsg(msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
recallMsg(peer: Peer, msgIds: string[]): Promise<GeneralCallResult>;
|
recallMsg(peer: Peer, msgIds: string[]): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
@@ -117,7 +130,7 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
addLocalRecordMsg(Peer: Peer, msgId: string, ele: MessageElement, attr: Array<any> | number, front: boolean): Promise<unknown>;
|
addLocalRecordMsg(Peer: Peer, msgId: string, ele: MessageElement, attr: Array<any> | number, front: boolean): Promise<unknown>;
|
||||||
|
|
||||||
deleteMsg(...args: unknown[]): unknown;
|
deleteMsg(Peer: Peer, msgIds: Array<string>): Promise<any>;
|
||||||
|
|
||||||
updateElementExtBufForUI(...args: unknown[]): unknown;
|
updateElementExtBufForUI(...args: unknown[]): unknown;
|
||||||
|
|
||||||
@@ -178,14 +191,14 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
getSingleMsg(Peer: Peer, msgSeq: string): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
|
getSingleMsg(Peer: Peer, msgSeq: string): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
|
||||||
|
|
||||||
getSourceOfReplyMsg(...args: unknown[]): unknown;
|
getSourceOfReplyMsg(peer: Peer, MsgId: string, SourceSeq: string): unknown;
|
||||||
|
|
||||||
getSourceOfReplyMsgV2(...args: unknown[]): unknown;
|
getSourceOfReplyMsgV2(peer: Peer, RootMsgId: string, ReplyMsgId: string): unknown;
|
||||||
|
|
||||||
getMsgByClientSeqAndTime(...args: unknown[]): unknown;
|
getMsgByClientSeqAndTime(peer: Peer, clientSeq: string, time: string): unknown;
|
||||||
|
|
||||||
getSourceOfReplyMsgByClientSeqAndTime(...args: unknown[]): unknown;
|
|
||||||
|
|
||||||
|
getSourceOfReplyMsgByClientSeqAndTime(peer: Peer, clientSeq: string, time: string): unknown;
|
||||||
|
//cnt clientSeq?并不是吧
|
||||||
getMsgsByTypeFilter(peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilter: { type: number, subtype: Array<number> }): unknown;
|
getMsgsByTypeFilter(peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilter: { type: number, subtype: Array<number> }): unknown;
|
||||||
|
|
||||||
getMsgsByTypeFilters(peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilters: Array<{ type: number, subtype: Array<number> }>): unknown;
|
getMsgsByTypeFilters(peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilters: Array<{ type: number, subtype: Array<number> }>): unknown;
|
||||||
@@ -214,19 +227,7 @@ export interface NodeIKernelMsgService {
|
|||||||
* @param param.isIncludeCurrent 是否包含当前页码。
|
* @param param.isIncludeCurrent 是否包含当前页码。
|
||||||
* @returns 返回一个Promise,解析为查询结果的未知类型对象。
|
* @returns 返回一个Promise,解析为查询结果的未知类型对象。
|
||||||
*/
|
*/
|
||||||
queryMsgsWithFilterVer2(MsgId: string, MsgTime: string, param: {
|
queryMsgsWithFilterVer2(MsgId: string, MsgTime: string, param: QueryMsgsParams): Promise<unknown>;
|
||||||
chatInfo: {
|
|
||||||
chatType: number,
|
|
||||||
peerUid: string
|
|
||||||
},
|
|
||||||
filterMsgType: [],
|
|
||||||
filterSendersUid: Array<string>,
|
|
||||||
filterMsgFromTime: string,
|
|
||||||
filterMsgToTime: string,
|
|
||||||
pageLimit: number,
|
|
||||||
isReverseOrder: boolean,
|
|
||||||
isIncludeCurrent: boolean
|
|
||||||
}): Promise<unknown>;
|
|
||||||
|
|
||||||
// this.chatType = i2;
|
// this.chatType = i2;
|
||||||
// this.peerUid = str;
|
// this.peerUid = str;
|
||||||
@@ -243,19 +244,7 @@ export interface NodeIKernelMsgService {
|
|||||||
// this.isReverseOrder = z;
|
// this.isReverseOrder = z;
|
||||||
// this.isIncludeCurrent = z2;
|
// this.isIncludeCurrent = z2;
|
||||||
//queryMsgsWithFilterEx(0L, 0L, 0L, new QueryMsgsParams(new ChatInfo(2, str), new ArrayList(), new ArrayList(), 0L, 0L, 250, false, true))
|
//queryMsgsWithFilterEx(0L, 0L, 0L, new QueryMsgsParams(new ChatInfo(2, str), new ArrayList(), new ArrayList(), 0L, 0L, 250, false, true))
|
||||||
queryMsgsWithFilterEx(msgId: string, msgTime: string, megSeq: string, param: {
|
queryMsgsWithFilterEx(msgId: string, msgTime: string, megSeq: string, param: QueryMsgsParams): Promise<GeneralCallResult & {
|
||||||
chatInfo: {
|
|
||||||
chatType: number,
|
|
||||||
peerUid: string
|
|
||||||
},
|
|
||||||
filterMsgType: [],
|
|
||||||
filterSendersUid: string[],
|
|
||||||
filterMsgFromTime: string,
|
|
||||||
filterMsgToTime: string,
|
|
||||||
pageLimit: number,
|
|
||||||
isReverseOrder: boolean,
|
|
||||||
isIncludeCurrent: boolean
|
|
||||||
}): Promise<GeneralCallResult & {
|
|
||||||
msgList: RawMessage[]
|
msgList: RawMessage[]
|
||||||
}>;
|
}>;
|
||||||
//queryMsgsWithFilterEx(this.$msgId, this.$msgTime, this.$msgSeq, this.$param)
|
//queryMsgsWithFilterEx(this.$msgId, this.$msgTime, this.$msgSeq, this.$param)
|
||||||
@@ -263,39 +252,15 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
setMsgRichInfoFlag(...args: unknown[]): unknown;
|
setMsgRichInfoFlag(...args: unknown[]): unknown;
|
||||||
|
|
||||||
queryPicOrVideoMsgs(msgId: string, msgTime: string, megSeq: string, param: {
|
queryPicOrVideoMsgs(msgId: string, msgTime: string, megSeq: string, param: QueryMsgsParams): Promise<unknown>;
|
||||||
chatInfo: {
|
|
||||||
chatType: number,
|
|
||||||
peerUid: string
|
|
||||||
},
|
|
||||||
filterMsgType: [],
|
|
||||||
filterSendersUid: [],
|
|
||||||
filterMsgFromTime: string,
|
|
||||||
filterMsgToTime: string,
|
|
||||||
pageLimit: number,
|
|
||||||
isReverseOrder: boolean,
|
|
||||||
isIncludeCurrent: boolean
|
|
||||||
}): Promise<unknown>;
|
|
||||||
|
|
||||||
queryPicOrVideoMsgsDesktop(...args: unknown[]): unknown;
|
queryPicOrVideoMsgsDesktop(...args: unknown[]): unknown;
|
||||||
|
|
||||||
queryEmoticonMsgs(...args: unknown[]): unknown;
|
queryEmoticonMsgs(msgId: string, msgTime: string, msgSeq: string, Params: QueryMsgsParams): Promise<unknown>;
|
||||||
|
|
||||||
queryTroopEmoticonMsgs(...args: unknown[]): unknown;
|
queryTroopEmoticonMsgs(msgId: string, msgTime: string, msgSeq: string, Params: QueryMsgsParams): Promise<unknown>;
|
||||||
|
|
||||||
queryMsgsAndAbstractsWithFilter(msgId: string, msgTime: string, megSeq: string, param: {
|
queryMsgsAndAbstractsWithFilter(msgId: string, msgTime: string, megSeq: string, param: QueryMsgsParams): unknown;
|
||||||
chatInfo: {
|
|
||||||
chatType: number,
|
|
||||||
peerUid: string
|
|
||||||
},
|
|
||||||
filterMsgType: [],
|
|
||||||
filterSendersUid: [],
|
|
||||||
filterMsgFromTime: string,
|
|
||||||
filterMsgToTime: string,
|
|
||||||
pageLimit: number,
|
|
||||||
isReverseOrder: boolean,
|
|
||||||
isIncludeCurrent: boolean
|
|
||||||
}): unknown;
|
|
||||||
|
|
||||||
setFocusOnGuild(...args: unknown[]): unknown;
|
setFocusOnGuild(...args: unknown[]): unknown;
|
||||||
|
|
||||||
@@ -534,7 +499,7 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
queryCalendar(...args: unknown[]): unknown;
|
queryCalendar(...args: unknown[]): unknown;
|
||||||
|
|
||||||
queryFirstMsgSeq(...args: unknown[]): unknown;
|
queryFirstMsgSeq(peer: Peer, ...args: unknown[]): unknown;
|
||||||
|
|
||||||
queryRoamCalendar(...args: unknown[]): unknown;
|
queryRoamCalendar(...args: unknown[]): unknown;
|
||||||
|
|
||||||
@@ -627,6 +592,8 @@ export interface NodeIKernelMsgService {
|
|||||||
// this.selfPhone = str5;
|
// this.selfPhone = str5;
|
||||||
// this.gameSession = tempChatGameSession;
|
// this.gameSession = tempChatGameSession;
|
||||||
prepareTempChat(args: unknown): unknown;//主动临时消息 不做
|
prepareTempChat(args: unknown): unknown;//主动临时消息 不做
|
||||||
|
|
||||||
|
sendSsoCmdReqByContend(cmd: string, param: string): Promise<unknown>;
|
||||||
|
|
||||||
//chattype,uid->Promise<any>
|
//chattype,uid->Promise<any>
|
||||||
getTempChatInfo(ChatType: number, Uid: string): unknown;
|
getTempChatInfo(ChatType: number, Uid: string): unknown;
|
||||||
|
@@ -2,8 +2,19 @@ import { AnyCnameRecord } from 'node:dns';
|
|||||||
import { BizKey, ModifyProfileParams, UserDetailInfoByUin } from '../entities';
|
import { BizKey, ModifyProfileParams, UserDetailInfoByUin } from '../entities';
|
||||||
import { NodeIKernelProfileListener } from '../listeners';
|
import { NodeIKernelProfileListener } from '../listeners';
|
||||||
import { GeneralCallResult } from '@/core/services/common';
|
import { GeneralCallResult } from '@/core/services/common';
|
||||||
|
export enum UserDetailSource {
|
||||||
|
KDB,
|
||||||
|
KSERVER
|
||||||
|
}
|
||||||
|
export enum ProfileBizType {
|
||||||
|
KALL,
|
||||||
|
KBASEEXTEND,
|
||||||
|
KVAS,
|
||||||
|
KQZONE,
|
||||||
|
KOTHER
|
||||||
|
}
|
||||||
export interface NodeIKernelProfileService {
|
export interface NodeIKernelProfileService {
|
||||||
|
fetchUserDetailInfo(trace: string, uids: string[], arg2: number, arg3: number[]): Promise<unknown>;
|
||||||
|
|
||||||
addKernelProfileListener(listener: NodeIKernelProfileListener): number;
|
addKernelProfileListener(listener: NodeIKernelProfileListener): number;
|
||||||
|
|
||||||
|
@@ -200,8 +200,6 @@ export interface NodeIKernelRichMediaService {
|
|||||||
|
|
||||||
getGroupFileInfo(arg1: unknown, arg2: unknown): unknown;
|
getGroupFileInfo(arg1: unknown, arg2: unknown): unknown;
|
||||||
|
|
||||||
getGroupFileList(arg1: unknown, arg2: unknown): unknown;
|
|
||||||
|
|
||||||
getGroupTransferList(arg1: unknown, arg2: unknown): unknown;
|
getGroupTransferList(arg1: unknown, arg2: unknown): unknown;
|
||||||
|
|
||||||
renameGroupFile(arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): unknown;
|
renameGroupFile(arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): unknown;
|
||||||
|
@@ -42,6 +42,7 @@ import { NodeIKernelCollectionService } from './services/NodeIKernelCollectionSe
|
|||||||
import { NodeIKernelRecentContactService } from './services/NodeIKernelRecentContactService';
|
import { NodeIKernelRecentContactService } from './services/NodeIKernelRecentContactService';
|
||||||
import { NodeIKernelMSFService } from './services/NodeIKernelMSFService';
|
import { NodeIKernelMSFService } from './services/NodeIKernelMSFService';
|
||||||
import { NodeIkernelTestPerformanceService } from './services/NodeIkernelTestPerformanceService';
|
import { NodeIkernelTestPerformanceService } from './services/NodeIkernelTestPerformanceService';
|
||||||
|
import { NodeIKernelECDHService } from './services/NodeIKernelECDHService';
|
||||||
|
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
@@ -157,6 +158,10 @@ export interface NodeIQQNTWrapperSession {
|
|||||||
|
|
||||||
startNT(): void;
|
startNT(): void;
|
||||||
|
|
||||||
|
getBdhUploadService(): unknown;
|
||||||
|
|
||||||
|
getECDHService(): NodeIKernelECDHService;
|
||||||
|
|
||||||
getMsgService(): NodeIKernelMsgService;
|
getMsgService(): NodeIKernelMsgService;
|
||||||
|
|
||||||
getProfileService(): NodeIKernelProfileService;
|
getProfileService(): NodeIKernelProfileService;
|
||||||
|
32
src/onebot11/action/extends/TestApi01.ts
Normal file
32
src/onebot11/action/extends/TestApi01.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import BaseAction from '../BaseAction';
|
||||||
|
import { ActionName, BaseCheckResult } from '../types';
|
||||||
|
import * as fs from 'node:fs';
|
||||||
|
import { NTQQUserApi } from '@/core/apis/user';
|
||||||
|
import { checkFileReceived, uri2local } from '@/common/utils/file';
|
||||||
|
import { napCatCore, NTQQGroupApi } from '@/core';
|
||||||
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
|
// import { log } from "../../../common/utils";
|
||||||
|
|
||||||
|
const SchemaData = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
cmd: { type: 'string' },
|
||||||
|
param: { type: 'string' }
|
||||||
|
},
|
||||||
|
required: ['cmd', 'param'],
|
||||||
|
} as const satisfies JSONSchema;
|
||||||
|
|
||||||
|
type Payload = FromSchema<typeof SchemaData>;
|
||||||
|
|
||||||
|
export default class TestApi01 extends BaseAction<Payload, any> {
|
||||||
|
actionName = ActionName.TestApi01;
|
||||||
|
// 用不着复杂检测
|
||||||
|
protected async check(payload: Payload): Promise<BaseCheckResult> {
|
||||||
|
return {
|
||||||
|
valid: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
protected async _handle(payload: Payload): Promise<any> {
|
||||||
|
return await napCatCore.session.getMsgService().sendSsoCmdReqByContend(payload.cmd, payload.param);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,15 +1,12 @@
|
|||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { ob11Config } from '@/onebot11/config';
|
import { ob11Config } from '@/onebot11/config';
|
||||||
import { log, logDebug } from '@/common/utils/log';
|
import { UUIDConverter } from '@/common/utils/helper';
|
||||||
import { sleep } from '@/common/utils/helper';
|
|
||||||
import { uri2local } from '@/common/utils/file';
|
|
||||||
import { ActionName, BaseCheckResult } from '../types';
|
import { ActionName, BaseCheckResult } from '../types';
|
||||||
import { ChatType, FileElement, Peer, RawMessage, VideoElement } from '@/core/entities';
|
import { ChatType, ElementType, FileElement, Peer, RawMessage, VideoElement } from '@/core/entities';
|
||||||
import { NTQQFileApi, NTQQMsgApi } from '@/core/apis';
|
import { NTQQFileApi, NTQQFriendApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis';
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
import Ajv from 'ajv';
|
import { getGroup } from '@/core/data';
|
||||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
|
||||||
|
|
||||||
export interface GetFilePayload {
|
export interface GetFilePayload {
|
||||||
file: string; // 文件名或者fileUuid
|
file: string; // 文件名或者fileUuid
|
||||||
@@ -46,6 +43,65 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
|||||||
}
|
}
|
||||||
protected async _handle(payload: GetFilePayload): Promise<GetFileResponse> {
|
protected async _handle(payload: GetFilePayload): Promise<GetFileResponse> {
|
||||||
const { enableLocalFile2Url } = ob11Config;
|
const { enableLocalFile2Url } = ob11Config;
|
||||||
|
let UuidData: {
|
||||||
|
high: string;
|
||||||
|
low: string;
|
||||||
|
} | undefined;
|
||||||
|
try {
|
||||||
|
UuidData = UUIDConverter.decode(payload.file);
|
||||||
|
if (UuidData) {
|
||||||
|
const peerUin = UuidData.high;
|
||||||
|
const msgId = UuidData.low;
|
||||||
|
const isGroup = await getGroup(peerUin);
|
||||||
|
let peer: Peer | undefined;
|
||||||
|
//识别Peer
|
||||||
|
if (isGroup) {
|
||||||
|
peer = { chatType: ChatType.group, peerUid: peerUin };
|
||||||
|
}
|
||||||
|
const PeerUid = await NTQQUserApi.getUidByUin(peerUin);
|
||||||
|
if (PeerUid) {
|
||||||
|
const isBuddy = await NTQQFriendApi.isBuddy(PeerUid);
|
||||||
|
if (isBuddy) {
|
||||||
|
peer = { chatType: ChatType.friend, peerUid: PeerUid };
|
||||||
|
} else {
|
||||||
|
peer = { chatType: ChatType.temp, peerUid: PeerUid };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!peer) {
|
||||||
|
throw new Error('chattype not support');
|
||||||
|
}
|
||||||
|
const msgList = await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]);
|
||||||
|
if (msgList.msgList.length == 0) {
|
||||||
|
throw new Error('msg not found');
|
||||||
|
}
|
||||||
|
const msg = msgList.msgList[0];
|
||||||
|
const findEle = msg.elements.find(e => e.elementType == ElementType.VIDEO || e.elementType == ElementType.FILE || e.elementType == ElementType.PTT);
|
||||||
|
if (!findEle) {
|
||||||
|
throw new Error('element not found');
|
||||||
|
}
|
||||||
|
const downloadPath = await NTQQFileApi.downloadMedia(msgId, msg.chatType, msg.peerUid, findEle.elementId, '', '');
|
||||||
|
const fileSize = findEle?.videoElement?.fileSize || findEle?.fileElement?.fileSize || findEle?.pttElement?.fileSize || '0';
|
||||||
|
const fileName = findEle?.videoElement?.fileName || findEle?.fileElement?.fileName || findEle?.pttElement?.fileName || '';
|
||||||
|
const res: GetFileResponse = {
|
||||||
|
file: downloadPath,
|
||||||
|
url: downloadPath,
|
||||||
|
file_size: fileSize,
|
||||||
|
file_name: fileName
|
||||||
|
};
|
||||||
|
if (enableLocalFile2Url) {
|
||||||
|
try {
|
||||||
|
res.base64 = await fs.readFile(downloadPath, 'base64');
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('文件下载失败. ' + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//不手动删除?文件持久化了
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems;
|
const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems;
|
||||||
if (NTSearchNameResult.length !== 0) {
|
if (NTSearchNameResult.length !== 0) {
|
||||||
const MsgId = NTSearchNameResult[0].msgId;
|
const MsgId = NTSearchNameResult[0].msgId;
|
||||||
@@ -69,7 +125,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
|||||||
const res: GetFileResponse = {
|
const res: GetFileResponse = {
|
||||||
file: downloadPath,
|
file: downloadPath,
|
||||||
url: downloadPath,
|
url: downloadPath,
|
||||||
file_size: NTSearchNameResult[0].fileSize.toString(),
|
file_size: NTSearchNameResult[0].fileSize.toString(),
|
||||||
file_name: NTSearchNameResult[0].fileName
|
file_name: NTSearchNameResult[0].fileName
|
||||||
};
|
};
|
||||||
if (enableLocalFile2Url) {
|
if (enableLocalFile2Url) {
|
||||||
@@ -82,7 +138,6 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
|||||||
//不手动删除?文件持久化了
|
//不手动删除?文件持久化了
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
//下面逻辑是有UUID的情况
|
|
||||||
throw new Error('file not found');
|
throw new Error('file not found');
|
||||||
// let cache = await dbUtil.getFileCacheByName(payload.file);
|
// let cache = await dbUtil.getFileCacheByName(payload.file);
|
||||||
// if (!cache) {
|
// if (!cache) {
|
||||||
|
@@ -2,7 +2,7 @@ import BaseAction from '../BaseAction';
|
|||||||
import { OB11Message, OB11User } from '../../types';
|
import { OB11Message, OB11User } from '../../types';
|
||||||
import { getGroup, groups } from '@/core/data';
|
import { getGroup, groups } from '@/core/data';
|
||||||
import { ActionName } from '../types';
|
import { ActionName } from '../types';
|
||||||
import { ChatType } from '@/core/entities';
|
import { ChatType, RawMessage } from '@/core/entities';
|
||||||
import { NTQQMsgApi } from '@/core/apis/msg';
|
import { NTQQMsgApi } from '@/core/apis/msg';
|
||||||
import { OB11Constructor } from '../../constructor';
|
import { OB11Constructor } from '../../constructor';
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
@@ -36,13 +36,13 @@ export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Resp
|
|||||||
chatType: ChatType.group,
|
chatType: ChatType.group,
|
||||||
peerUid: group.groupCode
|
peerUid: group.groupCode
|
||||||
};
|
};
|
||||||
|
let msgList: RawMessage[];
|
||||||
if (!payload.message_seq) {
|
if (!payload.message_seq) {
|
||||||
const latestMsgId = (await NTQQMsgApi.getLastestMsgByUids(peer)).msgList[0].msgId;
|
msgList = (await NTQQMsgApi.getLastestMsgByUids(peer, count)).msgList;
|
||||||
targetMsgShortId = await MessageUnique.createMsg(peer, latestMsgId || '0');
|
} else {
|
||||||
|
const startMsgId = (await MessageUnique.getMsgIdAndPeerByShortId(targetMsgShortId ?? (payload.message_seq ?? 0)))?.MsgId || '0';
|
||||||
|
msgList = (await NTQQMsgApi.getMsgHistory(peer, startMsgId, count)).msgList;
|
||||||
}
|
}
|
||||||
const startMsgId = (await MessageUnique.getMsgIdAndPeerByShortId(targetMsgShortId ?? (payload.message_seq ?? 0)))?.MsgId || '0';
|
|
||||||
const historyResult = (await NTQQMsgApi.getMsgHistory(peer, startMsgId, count));
|
|
||||||
const msgList = historyResult.msgList;
|
|
||||||
await Promise.all(msgList.map(async msg => {
|
await Promise.all(msgList.map(async msg => {
|
||||||
msg.id = await MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId);
|
msg.id = await MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId);
|
||||||
}));
|
}));
|
||||||
|
@@ -77,6 +77,7 @@ import { GetProfileLike } from './extends/GetProfileLike';
|
|||||||
import SetGroupHeader from './extends/SetGroupHeader';
|
import SetGroupHeader from './extends/SetGroupHeader';
|
||||||
import { FetchCustomFace } from './extends/FetchCustomFace';
|
import { FetchCustomFace } from './extends/FetchCustomFace';
|
||||||
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivareFile';
|
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivareFile';
|
||||||
|
import TestApi01 from './extends/TestApi01';
|
||||||
|
|
||||||
export const actionHandlers = [
|
export const actionHandlers = [
|
||||||
new RebootNormal(),
|
new RebootNormal(),
|
||||||
@@ -160,9 +161,9 @@ export const actionHandlers = [
|
|||||||
new GetProfileLike(),
|
new GetProfileLike(),
|
||||||
new SetGroupHeader(),
|
new SetGroupHeader(),
|
||||||
new FetchCustomFace(),
|
new FetchCustomFace(),
|
||||||
new GoCQHTTPUploadPrivateFile()
|
new GoCQHTTPUploadPrivateFile(),
|
||||||
|
new TestApi01()
|
||||||
];
|
];
|
||||||
|
|
||||||
function initActionMap() {
|
function initActionMap() {
|
||||||
const actionMap = new Map<string, BaseAction<any, any>>();
|
const actionMap = new Map<string, BaseAction<any, any>>();
|
||||||
for (const action of actionHandlers) {
|
for (const action of actionHandlers) {
|
||||||
|
@@ -32,10 +32,18 @@ class GetMsg extends BaseAction<Payload, OB11Message> {
|
|||||||
if (!msgIdWithPeer) {
|
if (!msgIdWithPeer) {
|
||||||
throw ('消息不存在');
|
throw ('消息不存在');
|
||||||
}
|
}
|
||||||
|
const peer = { guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType };
|
||||||
const msg = await NTQQMsgApi.getMsgsByMsgId(
|
const msg = await NTQQMsgApi.getMsgsByMsgId(
|
||||||
{ guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType },
|
peer,
|
||||||
[msgIdWithPeer?.MsgId || payload.message_id.toString()]);
|
[msgIdWithPeer?.MsgId || payload.message_id.toString()]);
|
||||||
return await OB11Constructor.message(msg.msgList[0]);
|
const retMsg = await OB11Constructor.message(msg.msgList[0]);
|
||||||
|
try {
|
||||||
|
retMsg.message_id = MessageUnique.createMsg(peer, msg.msgList[0].msgId)!;
|
||||||
|
retMsg.message_seq = retMsg.message_id;
|
||||||
|
retMsg.real_id = retMsg.message_id;
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
return retMsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,25 +12,22 @@ import {
|
|||||||
SignMusicWrapper
|
SignMusicWrapper
|
||||||
} from '@/core';
|
} from '@/core';
|
||||||
import { getGroupMember } from '@/core/data';
|
import { getGroupMember } from '@/core/data';
|
||||||
import { logDebug, logError, logWarn } from '@/common/utils/log';
|
import { logError, logWarn } from '@/common/utils/log';
|
||||||
import { uri2local } from '@/common/utils/file';
|
import { uri2local } from '@/common/utils/file';
|
||||||
import { ob11Config } from '@/onebot11/config';
|
import { ob11Config } from '@/onebot11/config';
|
||||||
import { RequestUtil } from '@/common/utils/request';
|
import { RequestUtil } from '@/common/utils/request';
|
||||||
import fs from 'node:fs';
|
|
||||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||||
|
|
||||||
export type MessageContext = {
|
export type MessageContext = {
|
||||||
group?: Group,
|
group?: Group,
|
||||||
deleteAfterSentFiles: string[],
|
deleteAfterSentFiles: string[],
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleOb11FileLikeMessage(
|
async function handleOb11FileLikeMessage(
|
||||||
{ data: { file, name: payloadFileName } }: OB11MessageFileBase,
|
{ data: inputdata }: OB11MessageFileBase,
|
||||||
{ deleteAfterSentFiles }: MessageContext
|
{ deleteAfterSentFiles }: MessageContext
|
||||||
) {
|
) {
|
||||||
const uri = file;
|
//有的奇怪的框架将url作为参数 而不是file 此时优先url
|
||||||
|
const { path, isLocal, fileName, errMsg } = (await uri2local(inputdata?.url || inputdata.file));
|
||||||
const { path, isLocal, fileName, errMsg } = (await uri2local(uri));
|
|
||||||
|
|
||||||
if (errMsg) {
|
if (errMsg) {
|
||||||
logError('文件下载失败', errMsg);
|
logError('文件下载失败', errMsg);
|
||||||
@@ -41,7 +38,7 @@ async function handleOb11FileLikeMessage(
|
|||||||
deleteAfterSentFiles.push(path);
|
deleteAfterSentFiles.push(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { path, fileName: payloadFileName || fileName };
|
return { path, fileName: inputdata.name || fileName };
|
||||||
}
|
}
|
||||||
|
|
||||||
const _handlers: {
|
const _handlers: {
|
||||||
|
@@ -101,5 +101,6 @@ export enum ActionName {
|
|||||||
GetProfileLike = 'get_profile_like',
|
GetProfileLike = 'get_profile_like',
|
||||||
SetGroupHeader = 'set_group_head',
|
SetGroupHeader = 'set_group_head',
|
||||||
FetchCustomFace = 'fetch_custom_face',
|
FetchCustomFace = 'fetch_custom_face',
|
||||||
GOCQHTTP_UploadPrivateFile = 'upload_private_file'
|
GOCQHTTP_UploadPrivateFile = 'upload_private_file',
|
||||||
|
TestApi01 = 'test_api_01'
|
||||||
}
|
}
|
||||||
|
@@ -35,7 +35,7 @@ import { OB11GroupNoticeEvent } from './event/notice/OB11GroupNoticeEvent';
|
|||||||
|
|
||||||
import { calcQQLevel } from '../common/utils/qqlevel';
|
import { calcQQLevel } from '../common/utils/qqlevel';
|
||||||
import { log, logDebug, logError, logWarn } from '../common/utils/log';
|
import { log, logDebug, logError, logWarn } from '../common/utils/log';
|
||||||
import { sleep } from '../common/utils/helper';
|
import { sleep, UUIDConverter } from '../common/utils/helper';
|
||||||
import { OB11GroupTitleEvent } from './event/notice/OB11GroupTitleEvent';
|
import { OB11GroupTitleEvent } from './event/notice/OB11GroupTitleEvent';
|
||||||
import { OB11GroupCardEvent } from './event/notice/OB11GroupCardEvent';
|
import { OB11GroupCardEvent } from './event/notice/OB11GroupCardEvent';
|
||||||
import { OB11GroupDecreaseEvent } from './event/notice/OB11GroupDecreaseEvent';
|
import { OB11GroupDecreaseEvent } from './event/notice/OB11GroupDecreaseEvent';
|
||||||
@@ -44,6 +44,7 @@ import { deleteGroup, getGroupMember, groupMembers, selfInfo, tempGroupCodeMap }
|
|||||||
import { NTQQFileApi, NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis';
|
import { NTQQFileApi, NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis';
|
||||||
import { OB11GroupMsgEmojiLikeEvent } from '@/onebot11/event/notice/OB11MsgEmojiLikeEvent';
|
import { OB11GroupMsgEmojiLikeEvent } from '@/onebot11/event/notice/OB11MsgEmojiLikeEvent';
|
||||||
import { OB11FriendPokeEvent, OB11GroupPokeEvent } from './event/notice/OB11PokeEvent';
|
import { OB11FriendPokeEvent, OB11GroupPokeEvent } from './event/notice/OB11PokeEvent';
|
||||||
|
import { OB11FriendAddNoticeEvent } from './event/notice/OB11FriendAddNoticeEvent';
|
||||||
import { OB11BaseNoticeEvent } from './event/notice/OB11BaseNoticeEvent';
|
import { OB11BaseNoticeEvent } from './event/notice/OB11BaseNoticeEvent';
|
||||||
import { OB11GroupEssenceEvent } from './event/notice/OB11GroupEssenceEvent';
|
import { OB11GroupEssenceEvent } from './event/notice/OB11GroupEssenceEvent';
|
||||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||||
@@ -100,33 +101,40 @@ export class OB11Constructor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const element of msg.elements) {
|
for (const element of msg.elements) {
|
||||||
const message_data: OB11MessageData | any = {
|
let message_data: OB11MessageData = {
|
||||||
data: {},
|
data: {} as any,
|
||||||
type: 'unknown'
|
type: 'unknown' as any
|
||||||
};
|
};
|
||||||
if (element.textElement && element.textElement?.atType !== AtType.notAt) {
|
if (element.textElement && element.textElement?.atType !== AtType.notAt) {
|
||||||
message_data['type'] = OB11MessageDataType.at;
|
let qq: `${number}` | 'all';
|
||||||
|
let name: string | undefined;
|
||||||
if (element.textElement.atType == AtType.atAll) {
|
if (element.textElement.atType == AtType.atAll) {
|
||||||
// message_data["data"]["mention"] = "all"
|
qq = 'all';
|
||||||
message_data['data']['qq'] = 'all';
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const atUid = element.textElement.atNtUid;
|
const { atNtUid, content } = element.textElement;
|
||||||
let atQQ = element.textElement.atUid;
|
let atQQ = element.textElement.atUid;
|
||||||
if (!atQQ || atQQ === '0') {
|
if (!atQQ || atQQ === '0') {
|
||||||
const atMember = await getGroupMember(msg.peerUin, atUid);
|
const atMember = await getGroupMember(msg.peerUin, atNtUid);
|
||||||
if (atMember) {
|
if (atMember) {
|
||||||
atQQ = atMember.uin;
|
atQQ = atMember.uin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (atQQ) {
|
if (atQQ) {
|
||||||
// message_data["data"]["mention"] = atQQ
|
qq = atQQ as `${number}`;
|
||||||
message_data['data']['qq'] = atQQ;
|
name = content.replace('@', '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
message_data = {
|
||||||
|
type: OB11MessageDataType.at,
|
||||||
|
data: {
|
||||||
|
qq: qq!,
|
||||||
|
name
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else if (element.textElement) {
|
else if (element.textElement) {
|
||||||
message_data['type'] = 'text';
|
message_data['type'] = OB11MessageDataType.text;
|
||||||
|
|
||||||
let text = element.textElement.content;
|
let text = element.textElement.content;
|
||||||
if (!text.trim()) {
|
if (!text.trim()) {
|
||||||
@@ -139,7 +147,7 @@ export class OB11Constructor {
|
|||||||
message_data['data']['text'] = text;
|
message_data['data']['text'] = text;
|
||||||
}
|
}
|
||||||
else if (element.replyElement) {
|
else if (element.replyElement) {
|
||||||
message_data['type'] = 'reply';
|
message_data['type'] = OB11MessageDataType.reply;
|
||||||
//log("收到回复消息", element.replyElement);
|
//log("收到回复消息", element.replyElement);
|
||||||
try {
|
try {
|
||||||
//做这么多都是因为NC速度太快 可能nt还没有写入数据库
|
//做这么多都是因为NC速度太快 可能nt还没有写入数据库
|
||||||
@@ -162,17 +170,18 @@ export class OB11Constructor {
|
|||||||
message_data['data']['id'] = MessageUnique.createMsg({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, replyMsg.msgId)?.toString();
|
message_data['data']['id'] = MessageUnique.createMsg({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, replyMsg.msgId)?.toString();
|
||||||
//log("找到回复消息", message_data['data']['id'], replyMsg.msgList[0].msgId)
|
//log("找到回复消息", message_data['data']['id'], replyMsg.msgList[0].msgId)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
message_data['type'] = "unknown";
|
message_data['type'] = 'unknown' as any;
|
||||||
message_data['data'] = undefined;
|
message_data['data'] = undefined;
|
||||||
logError('获取不到引用的消息', e.stack, element.replyElement.replayMsgSeq);
|
logError('获取不到引用的消息', e.stack, element.replyElement.replayMsgSeq);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (element.picElement) {
|
else if (element.picElement) {
|
||||||
message_data['type'] = 'image';
|
message_data['type'] = OB11MessageDataType.image;
|
||||||
// message_data["data"]["file"] = element.picElement.sourcePath
|
// message_data["data"]["file"] = element.picElement.sourcePath
|
||||||
message_data['data']['file'] = element.picElement.fileName;
|
message_data['data']['file'] = element.picElement.fileName;
|
||||||
message_data['data']['subType'] = element.picElement.picSubType;
|
message_data['data']['subType'] = element.picElement.picSubType;
|
||||||
|
message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId);
|
||||||
// message_data["data"]["path"] = element.picElement.sourcePath
|
// message_data["data"]["path"] = element.picElement.sourcePath
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -185,26 +194,25 @@ export class OB11Constructor {
|
|||||||
message_data['data']['file_size'] = element.picElement.fileSize;
|
message_data['data']['file_size'] = element.picElement.fileSize;
|
||||||
}
|
}
|
||||||
else if (element.fileElement) {
|
else if (element.fileElement) {
|
||||||
|
|
||||||
const FileElement = element.fileElement;
|
const FileElement = element.fileElement;
|
||||||
message_data['type'] = OB11MessageDataType.file;
|
message_data['type'] = OB11MessageDataType.file;
|
||||||
message_data['data']['file'] = FileElement.fileName;
|
message_data['data']['file'] = FileElement.fileName;
|
||||||
message_data['data']['path'] = FileElement.filePath;
|
message_data['data']['path'] = FileElement.filePath;
|
||||||
message_data['data']['url'] = FileElement.filePath;
|
message_data['data']['url'] = FileElement.filePath;
|
||||||
message_data['data']['file_id'] = FileElement.fileUuid;
|
message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId);
|
||||||
message_data['data']['file_size'] = FileElement.fileSize;
|
message_data['data']['file_size'] = FileElement.fileSize;
|
||||||
await NTQQFileApi.addFileCache({
|
await NTQQFileApi.addFileCache({
|
||||||
peerUid: msg.peerUid,
|
peerUid: msg.peerUid,
|
||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
},
|
},
|
||||||
msg.msgId,
|
msg.msgId,
|
||||||
msg.msgSeq,
|
msg.msgSeq,
|
||||||
msg.senderUid,
|
msg.senderUid,
|
||||||
element.elementId,
|
element.elementId,
|
||||||
element.elementType.toString(),
|
element.elementType.toString(),
|
||||||
FileElement.fileSize,
|
FileElement.fileSize,
|
||||||
FileElement.fileName
|
FileElement.fileName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (element.videoElement) {
|
else if (element.videoElement) {
|
||||||
@@ -237,7 +245,7 @@ export class OB11Constructor {
|
|||||||
message_data['data']['file'] = videoElement.fileName;
|
message_data['data']['file'] = videoElement.fileName;
|
||||||
message_data['data']['path'] = videoDownUrl;
|
message_data['data']['path'] = videoDownUrl;
|
||||||
message_data['data']['url'] = videoDownUrl;
|
message_data['data']['url'] = videoDownUrl;
|
||||||
message_data['data']['file_id'] = videoElement.fileUuid;
|
message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId);
|
||||||
message_data['data']['file_size'] = videoElement.fileSize;
|
message_data['data']['file_size'] = videoElement.fileSize;
|
||||||
|
|
||||||
await NTQQFileApi.addFileCache({
|
await NTQQFileApi.addFileCache({
|
||||||
@@ -245,44 +253,34 @@ export class OB11Constructor {
|
|||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
},
|
},
|
||||||
msg.msgId,
|
msg.msgId,
|
||||||
msg.msgSeq,
|
msg.msgSeq,
|
||||||
msg.senderUid,
|
msg.senderUid,
|
||||||
element.elementId,
|
element.elementId,
|
||||||
element.elementType.toString(),
|
element.elementType.toString(),
|
||||||
videoElement.fileSize || '0',
|
videoElement.fileSize || '0',
|
||||||
videoElement.fileName
|
videoElement.fileName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (element.pttElement) {
|
else if (element.pttElement) {
|
||||||
message_data['type'] = OB11MessageDataType.voice;
|
message_data['type'] = OB11MessageDataType.voice;
|
||||||
message_data['data']['file'] = element.pttElement.fileName;
|
message_data['data']['file'] = element.pttElement.fileName;
|
||||||
message_data['data']['path'] = element.pttElement.filePath;
|
message_data['data']['path'] = element.pttElement.filePath;
|
||||||
message_data['data']['file_id'] = element.pttElement.fileUuid;
|
//message_data['data']['file_id'] = element.pttElement.fileUuid;
|
||||||
|
message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId);
|
||||||
message_data['data']['file_size'] = element.pttElement.fileSize;
|
message_data['data']['file_size'] = element.pttElement.fileSize;
|
||||||
// dbUtil.addFileCache({
|
|
||||||
// name: element.pttElement.fileName,
|
|
||||||
// path: element.pttElement.filePath,
|
|
||||||
// size: parseInt(element.pttElement.fileSize) || 0,
|
|
||||||
// url: '',
|
|
||||||
// uuid: element.pttElement.fileUuid || '',
|
|
||||||
// msgId: msg.msgId,
|
|
||||||
// element: element.pttElement,
|
|
||||||
// elementType: ElementType.PTT,
|
|
||||||
// elementId: element.elementId
|
|
||||||
// }).then();
|
|
||||||
await NTQQFileApi.addFileCache({
|
await NTQQFileApi.addFileCache({
|
||||||
peerUid: msg.peerUid,
|
peerUid: msg.peerUid,
|
||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
},
|
},
|
||||||
msg.msgId,
|
msg.msgId,
|
||||||
msg.msgSeq,
|
msg.msgSeq,
|
||||||
msg.senderUid,
|
msg.senderUid,
|
||||||
element.elementId,
|
element.elementId,
|
||||||
element.elementType.toString(),
|
element.elementType.toString(),
|
||||||
element.pttElement.fileSize || '0',
|
element.pttElement.fileSize || '0',
|
||||||
element.pttElement.fileUuid || ''
|
element.pttElement.fileUuid || ''
|
||||||
);
|
);
|
||||||
//以uuid作为文件名
|
//以uuid作为文件名
|
||||||
}
|
}
|
||||||
@@ -328,7 +326,7 @@ export class OB11Constructor {
|
|||||||
message_data['type'] = OB11MessageDataType.forward;
|
message_data['type'] = OB11MessageDataType.forward;
|
||||||
message_data['data']['id'] = msg.msgId;
|
message_data['data']['id'] = msg.msgId;
|
||||||
}
|
}
|
||||||
if (message_data.type !== 'unknown' && message_data.data) {
|
if ((message_data.type as string) !== 'unknown' && message_data.data) {
|
||||||
const cqCode = encodeCQCode(message_data);
|
const cqCode = encodeCQCode(message_data);
|
||||||
|
|
||||||
if (messagePostFormat === 'string') {
|
if (messagePostFormat === 'string') {
|
||||||
@@ -350,6 +348,7 @@ export class OB11Constructor {
|
|||||||
if (element.grayTipElement) {
|
if (element.grayTipElement) {
|
||||||
if (element.grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE) {
|
if (element.grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE) {
|
||||||
const json = JSON.parse(element.grayTipElement.jsonGrayTipElement.jsonStr);
|
const json = JSON.parse(element.grayTipElement.jsonGrayTipElement.jsonStr);
|
||||||
|
|
||||||
if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) {
|
if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) {
|
||||||
//判断业务类型
|
//判断业务类型
|
||||||
//Poke事件
|
//Poke事件
|
||||||
@@ -358,11 +357,17 @@ export class OB11Constructor {
|
|||||||
pokedetail = pokedetail.filter(item => item.uid);
|
pokedetail = pokedetail.filter(item => item.uid);
|
||||||
//console.log("[NapCat] 群拍一拍 群:", pokedetail, parseInt(msg.peerUid), " ", await NTQQUserApi.getUinByUid(pokedetail[0].uid), "拍了拍", await NTQQUserApi.getUinByUid(pokedetail[1].uid));
|
//console.log("[NapCat] 群拍一拍 群:", pokedetail, parseInt(msg.peerUid), " ", await NTQQUserApi.getUinByUid(pokedetail[0].uid), "拍了拍", await NTQQUserApi.getUinByUid(pokedetail[1].uid));
|
||||||
if (pokedetail.length == 2) {
|
if (pokedetail.length == 2) {
|
||||||
return new OB11FriendPokeEvent(parseInt((await NTQQUserApi.getUinByUid(pokedetail[0].uid))!), parseInt((await NTQQUserApi.getUinByUid(pokedetail[1].uid))!));
|
return new OB11FriendPokeEvent(parseInt((await NTQQUserApi.getUinByUid(pokedetail[0].uid))!), parseInt((await NTQQUserApi.getUinByUid(pokedetail[1].uid))!), pokedetail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE
|
//下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE
|
||||||
}
|
}
|
||||||
|
if (element.grayTipElement.subElementType == GrayTipElementSubType.INVITE_NEW_MEMBER) {
|
||||||
|
//好友添加成功事件
|
||||||
|
if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') {
|
||||||
|
return new OB11FriendAddNoticeEvent(parseInt(msg.peerUin));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -66,16 +66,16 @@ export function encodeCQCode(data: OB11MessageData) {
|
|||||||
|
|
||||||
let result = '[CQ:' + data.type;
|
let result = '[CQ:' + data.type;
|
||||||
for (const name in data.data) {
|
for (const name in data.data) {
|
||||||
let value = data.data[name];
|
const value = data.data[name];
|
||||||
try {
|
if (value === undefined) {
|
||||||
// Check if the value can be converted to a string
|
|
||||||
value = value.toString();
|
|
||||||
} catch (error) {
|
|
||||||
// If it can't be converted, skip this name-value pair
|
|
||||||
// console.warn(`Skipping problematic name-value pair. Name: ${name}, Value: ${value}`);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
result += `,${name}=${CQCodeEscape(value)}`;
|
try {
|
||||||
|
const text = value.toString();
|
||||||
|
result += `,${name}=${CQCodeEscape(text)}`;
|
||||||
|
} catch (error) {
|
||||||
|
// If it can't be converted, skip this name-value pair
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result += ']';
|
result += ']';
|
||||||
return result;
|
return result;
|
||||||
|
11
src/onebot11/event/notice/OB11FriendAddNoticeEvent.ts
Normal file
11
src/onebot11/event/notice/OB11FriendAddNoticeEvent.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent';
|
||||||
|
|
||||||
|
export class OB11FriendAddNoticeEvent extends OB11BaseNoticeEvent {
|
||||||
|
notice_type = 'friend_add';
|
||||||
|
user_id: number;
|
||||||
|
|
||||||
|
public constructor(user_Id: number) {
|
||||||
|
super();
|
||||||
|
this.user_id = user_Id;
|
||||||
|
}
|
||||||
|
}
|
@@ -10,22 +10,25 @@ class OB11PokeEvent extends OB11BaseNoticeEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class OB11FriendPokeEvent extends OB11PokeEvent {
|
export class OB11FriendPokeEvent extends OB11PokeEvent {
|
||||||
constructor(user_id: number, target_id: number) {
|
raw_info: any;
|
||||||
|
//raw_message nb等框架标准为string
|
||||||
|
constructor(user_id: number, target_id: number, raw_message: any) {
|
||||||
super();
|
super();
|
||||||
this.target_id = target_id;
|
this.target_id = target_id;
|
||||||
this.user_id = user_id;
|
this.user_id = user_id;
|
||||||
|
this.raw_info = raw_message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OB11GroupPokeEvent extends OB11PokeEvent {
|
export class OB11GroupPokeEvent extends OB11PokeEvent {
|
||||||
group_id: number;
|
group_id: number;
|
||||||
raw_message: any;
|
raw_info: any;
|
||||||
|
//raw_message nb等框架标准为string
|
||||||
constructor(group_id: number, user_id: number = 0, target_id: number = 0, raw_message: any) {
|
constructor(group_id: number, user_id: number = 0, target_id: number = 0, raw_message: any) {
|
||||||
super();
|
super();
|
||||||
this.group_id = group_id;
|
this.group_id = group_id;
|
||||||
this.target_id = target_id;
|
this.target_id = target_id;
|
||||||
this.user_id = user_id;
|
this.user_id = user_id;
|
||||||
this.raw_message = raw_message;
|
this.raw_info = raw_message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -241,20 +241,20 @@ export class NapCatOnebot11 {
|
|||||||
msgListener.onMsgInfoListUpdate = (msgList) => {
|
msgListener.onMsgInfoListUpdate = (msgList) => {
|
||||||
this.postRecallMsg(msgList).then().catch(logError);
|
this.postRecallMsg(msgList).then().catch(logError);
|
||||||
for (const msg of msgList.filter(e => e.senderUin == selfInfo.uin)) {
|
for (const msg of msgList.filter(e => e.senderUin == selfInfo.uin)) {
|
||||||
// console.log(msg);
|
// console.log(msg);
|
||||||
if (msg.sendStatus !== 2) {
|
if (msg.sendStatus == 2) {
|
||||||
//完成后再post
|
//完成后再post
|
||||||
return;
|
OB11Constructor.message(msg).then((_msg) => {
|
||||||
|
_msg.target_id = parseInt(msg.peerUin);
|
||||||
|
if (ob11Config.reportSelfMessage) {
|
||||||
|
msg.id = MessageUnique.createMsg({ chatType: msg.chatType, peerUid: msg.peerUid, guildId: '' }, msg.msgId);
|
||||||
|
this.postReceiveMsg([msg]).then().catch(logError);
|
||||||
|
} else {
|
||||||
|
logMessage(_msg as OB11Message).then().catch(logError);
|
||||||
|
}
|
||||||
|
}).catch(logError);
|
||||||
}
|
}
|
||||||
OB11Constructor.message(msg).then((_msg) => {
|
|
||||||
_msg.target_id = parseInt(msg.peerUin);
|
|
||||||
if (ob11Config.reportSelfMessage) {
|
|
||||||
msg.id = MessageUnique.createMsg({ chatType: msg.chatType, peerUid: msg.peerUid, guildId: '' }, msg.msgId);
|
|
||||||
this.postReceiveMsg([msg]).then().catch(logError);
|
|
||||||
} else {
|
|
||||||
logMessage(_msg as OB11Message).then().catch(logError);
|
|
||||||
}
|
|
||||||
}).catch(logError);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
msgListener.onAddSendMsg = (msg) => {
|
msgListener.onAddSendMsg = (msg) => {
|
||||||
@@ -285,7 +285,7 @@ export class NapCatOnebot11 {
|
|||||||
// }
|
// }
|
||||||
groupListener.onGroupNotifiesUpdated = async (doubt, notifies) => {
|
groupListener.onGroupNotifiesUpdated = async (doubt, notifies) => {
|
||||||
//console.log('ob11 onGroupNotifiesUpdated', notifies[0]);
|
//console.log('ob11 onGroupNotifiesUpdated', notifies[0]);
|
||||||
if (![GroupNotifyTypes.INVITE_ME, GroupNotifyTypes.ADMIN_SET, GroupNotifyTypes.ADMIN_UNSET, GroupNotifyTypes.ADMIN_UNSET_OTHER].includes(notifies[0].type)) {
|
if (![GroupNotifyTypes.ADMIN_SET, GroupNotifyTypes.ADMIN_UNSET, GroupNotifyTypes.ADMIN_UNSET_OTHER].includes(notifies[0].type)) {
|
||||||
this.postGroupNotifies(notifies).then().catch(e => logError('postGroupNotifies error: ', e));
|
this.postGroupNotifies(notifies).then().catch(e => logError('postGroupNotifies error: ', e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -594,7 +594,7 @@ export class NapCatOnebot11 {
|
|||||||
|
|
||||||
async postFriendRequest(reqs: FriendRequest[]) {
|
async postFriendRequest(reqs: FriendRequest[]) {
|
||||||
for (const req of reqs) {
|
for (const req of reqs) {
|
||||||
if (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM) {
|
if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const friendRequestEvent = new OB11FriendRequestEvent();
|
const friendRequestEvent = new OB11FriendRequestEvent();
|
||||||
|
@@ -114,6 +114,7 @@ export interface OB11MessageAt {
|
|||||||
type: OB11MessageDataType.at
|
type: OB11MessageDataType.at
|
||||||
data: {
|
data: {
|
||||||
qq: `${number}` | 'all'
|
qq: `${number}` | 'all'
|
||||||
|
name?: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,13 +178,20 @@ export interface OB11MessageMarkdown {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OB11MessageForward {
|
||||||
|
type: OB11MessageDataType.forward
|
||||||
|
data: {
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type OB11MessageData =
|
export type OB11MessageData =
|
||||||
OB11MessageText |
|
OB11MessageText |
|
||||||
OB11MessageFace | OB11MessageMFace |
|
OB11MessageFace | OB11MessageMFace |
|
||||||
OB11MessageAt | OB11MessageReply |
|
OB11MessageAt | OB11MessageReply |
|
||||||
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
||||||
OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson |
|
OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson |
|
||||||
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown
|
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward
|
||||||
|
|
||||||
export interface OB11PostSendMsg {
|
export interface OB11PostSendMsg {
|
||||||
message_type?: 'private' | 'group'
|
message_type?: 'private' | 'group'
|
||||||
|
@@ -1 +1 @@
|
|||||||
export const version = '1.7.2';
|
export const version = '1.7.5';
|
||||||
|
@@ -29,7 +29,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('V1.7.2', 'napcat-update-button', 'secondary')
|
SettingButton('V1.7.5', 'napcat-update-button', 'secondary')
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
@@ -163,7 +163,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("V1.7.2", "napcat-update-button", "secondary")
|
SettingButton("V1.7.5", "napcat-update-button", "secondary")
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
Reference in New Issue
Block a user