Compare commits

...

27 Commits

Author SHA1 Message Date
手瓜一十雪
440b63f662 release: v1.7.4 2024-08-01 23:35:35 +08:00
手瓜一十雪
7d2cc3b56b fix: 多次上报自身消息 2024-08-01 22:00:40 +08:00
手瓜一十雪
5fe3422469 #176 revert 2024-08-01 21:48:17 +08:00
手瓜一十雪
6c02cedb1e build: 1.7.4 2024-08-01 19:44:28 +08:00
手瓜一十雪
3cc2f1dcad fix #183 2024-08-01 19:43:29 +08:00
手瓜一十雪
773cdc5877 build: test 2024-08-01 17:14:15 +08:00
手瓜一十雪
361a7329d7 Revert "build(deps-dev): bump @typescript-eslint/eslint-plugin"
This reverts commit 2562a38fa1.
2024-08-01 17:13:54 +08:00
手瓜一十雪
29910f1236 build: test api 2024-08-01 17:12:56 +08:00
手瓜一十雪
4a164016f5 chore: test 2024-08-01 17:08:22 +08:00
手瓜一十雪
cebd3e62a4 Merge pull request #192 from NapNeko/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-8.0.0
build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.18.0 to 8.0.0
2024-08-01 16:26:50 +08:00
dependabot[bot]
2562a38fa1 build(deps-dev): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.18.0 to 8.0.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.0.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-01 08:22:34 +00:00
手瓜一十雪
d46c922bbf Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-08-01 13:11:19 +08:00
手瓜一十雪
66b59982f7 补充类型 移除无用代码 2024-08-01 13:11:09 +08:00
手瓜一十雪
ad397ccf7f Merge pull request #188 from Fripine/feat/FriendAddNoticeEvent
feat: support FriendAddNoticeEvent
2024-08-01 08:46:50 +08:00
Fripine
bdef80ede7 feat: support FriendAddNoticeEvent 2024-08-01 01:03:33 +08:00
手瓜一十雪
385dcbc75a fix #186 2024-07-31 22:23:12 +08:00
手瓜一十雪
74cf501c8f release: 1.7.3 2024-07-31 22:21:23 +08:00
手瓜一十雪
0c200d6748 build: 1.7.2 beta0 2024-07-31 22:20:39 +08:00
手瓜一十雪
e65a36c517 chore: Ver2SendMsg 2024-07-31 22:19:35 +08:00
手瓜一十雪
126b54ad40 fix #186 2024-07-31 21:46:12 +08:00
手瓜一十雪
78637751af fix #187 2024-07-31 21:41:31 +08:00
手瓜一十雪
f96526ee3a fix #184 2024-07-31 21:36:13 +08:00
手瓜一十雪
b3c7a91f3d refactor: getfile 2024-07-31 16:40:34 +08:00
手瓜一十雪
b8daeef0c4 fix #173 2024-07-31 16:02:08 +08:00
手瓜一十雪
2b662944cf typo fix #178 2024-07-31 15:58:27 +08:00
手瓜一十雪
3d516df01e try fix #183 2024-07-31 15:52:28 +08:00
手瓜一十雪
26b4a9b15b chore: 兼容wt 2024-07-31 14:21:05 +08:00
22 changed files with 268 additions and 136 deletions

View File

@@ -2,7 +2,7 @@
"name": "napcat",
"private": true,
"type": "module",
"version": "1.7.2",
"version": "1.7.4",
"scripts": {
"watch:dev": "vite --mode development",
"watch:prod": "vite --mode production",

View File

@@ -8,6 +8,27 @@ import * as fsPromise from 'node:fs/promises';
const __filename = fileURLToPath(import.meta.url);
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> {
return new Promise(resolve => setTimeout(resolve, ms));
}

View File

@@ -4,10 +4,10 @@ export async function checkVersion(): Promise<string> {
return new Promise(async (resolve, reject) => {
const MirrorList =
[
'https://jsd.cdn.zzko.cn/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://cdn.jsdelivr.us/gh/NapNeko/NapCatQQ@main/package.json',
'https://jsd.cdn.zzko.cn/gh/NapNeko/NapCatQQ@main/package.json'
'https://cdn.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json'
];
let version = undefined;
for (const url of MirrorList) {

View File

@@ -18,6 +18,7 @@ import { sessionConfig } from '@/core/sessionConfig';
import { rkeyManager } from '../utils/rkey';
import { NTEventDispatch } from '@/common/utils/EventTask';
import { NodeIKernelSearchService } from '../services/NodeIKernelSearchService';
import { selfInfo } from '../data';
export class NTQQFileApi {
@@ -67,7 +68,9 @@ export class NTQQFileApi {
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) {
//logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force);
// 用于下载收到的消息中的图片等

View File

@@ -7,8 +7,6 @@ import { NodeIKernelMsgListener, onGroupFileInfoUpdateParamType } from '@/core/l
import { GeneralCallResult } from '@/core/services/common';
import { MessageUnique } from '../../../common/utils/MessageUnique';
import { NTEventDispatch } from '@/common/utils/EventTask';
import { logNotice } from '@/onebot11/log';
let MsgSendMode = 2;
async function LoadMessageIdList(Peer: Peer, msgId: string) {
let msgList = await NTQQMsgApi.getMsgHistory(Peer, msgId, 50);
@@ -42,8 +40,10 @@ async function loadMessageUnique() {
setTimeout(() => {
napCatCore.onLoginSuccess(async () => {
await sleep(100);
NTQQMsgApi.CheckSendMode().then().catch();
// NTQQMsgApi.CheckSendMode().then().catch();
loadMessageUnique().then().catch();
//let data = await napCatCore.session.getMsgService().sendSsoCmdReqByContend("LightAppSvc.mini_app_growguard.ReportExecute","1124343");
//console.log(data);
});
}, 100);
//歇菜LocalMsg压根不写Db
@@ -64,26 +64,29 @@ setTimeout(() => {
// ));
// console.log(await NTQQMsgApi.multiForwardMsg(peer, peer, [MsgId]));
// }, 25000)
let SendMsgSeq = new Map<Peer, Array<number>>();
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 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;
// enum BaseEmojiType {
// NORMAL_EMOJI,
@@ -141,9 +144,6 @@ export class NTQQMsgApi {
}
static async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) {
return await napCatCore.session.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z);
}
static async testMode() {
}
static async setMsgRead(peer: Peer) {
return napCatCore.session.getMsgService().setMsgRead(peer);
@@ -153,7 +153,7 @@ export class NTQQMsgApi {
(GroupCode: string, params: GetFileListParam) => Promise<unknown>,
(groupFileListResult: onGroupFileInfoUpdateParamType) => void
>(
'NodeIKernelRichMediaService/sendMsg',
'NodeIKernelRichMediaService/getGroupFileList',
'NodeIKernelMsgListener/onGroupFileInfoUpdate',
1,
5000,
@@ -175,6 +175,12 @@ export class NTQQMsgApi {
peerUid: peer.peerUid
}, msgIds);
}
//并发Seq
static async sendMsgV3(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
let msgList = await NTQQMsgApi.getLastestMsgByUids(peer);
let data = await napCatCore.session.getMsgService().sendMsg("0", peer, msgElements, new Map());
SendMsgSeq.get(peer)?.push()
}
static async sendMsgV2(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
// function generateMsgId() {
// const timestamp = Math.floor(Date.now() / 1000);
@@ -185,6 +191,7 @@ export class NTQQMsgApi {
// const msgId = BigInt("0x" + buffer.toString('hex')).toString();
// return msgId;
// }
let msgId = await NTQQMsgApi.getMsgUnique(await NTQQMsgApi.getServerTime());
let data = await NTEventDispatch.CallNormalEvent<
(msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>,
@@ -214,47 +221,40 @@ export class NTQQMsgApi {
});
return retMsg;
}
static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
if (MsgSendMode == 1) {
return NTQQMsgApi.sendMsgV1(peer, msgElements, waitComplete, timeout);
} else if (MsgSendMode == 2) {
return NTQQMsgApi.sendMsgV2(peer, msgElements, waitComplete, timeout);
}
throw new Error('未知的发送消息模式');
static sendMsgEx(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
//return NTQQMsgApi.sendMsgV1(peer, msgElements, waitComplete, timeout);
}
static async sendMsgV1(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
let msgList = await NTQQMsgApi.getLastestMsgByUids(peer);
let msgCurrentSeq = 0n;
if (msgList.msgList.length > 0) {
msgCurrentSeq = BigInt(msgList.msgList[0].msgSeq);
}
let rawMsg: RawMessage | undefined;
let EventListener = NTEventDispatch.RegisterListen<NodeIKernelMsgListener['onAddSendMsg']>('NodeIKernelMsgListener/onAddSendMsg', 1, timeout, (msg: RawMessage) => {
//console.log("msgSeq:", msgCurrentSeq.toString(), JSON.stringify(msgList.msgList[0], null, 4));
if (msg.peerUid == peer.peerUid && (msgCurrentSeq == 0n || msgList.msgList[0].msgSeq == msgCurrentSeq.toString())) {
rawMsg = msg;
return true;
}
return false;
}).catch(logError);
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;
static async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
//唉? !我有个想法
let msgId = await NTQQMsgApi.getMsgUnique(await NTQQMsgApi.getServerTime());
peer.guildId = msgId;
let data = await NTEventDispatch.CallNormalEvent<
(msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>,
(msgList: RawMessage[]) => void
>(
'NodeIKernelMsgService/sendMsg',
'NodeIKernelMsgListener/onMsgInfoListUpdate',
1,
timeout,
(msgRecords: RawMessage[]) => {
for (let msgRecord of msgRecords) {
if (msgRecord.guildId === msgId && msgRecord.sendStatus === 2) {
return true;
}
}
return false;
}).catch(logError);
await NTEventDispatch.CallNoListenerEvent<NodeIKernelMsgService['sendMsg']>('NodeIKernelMsgService/sendMsg', timeout, "0", peer, msgElements, new Map());
await EventListener;
await EventListener2;
// console.log("rawMsg", JSON.stringify(rawMsg, null, 4));
if (rawMsg) {
return rawMsg;
}
throw new Error('发送消息超时');
},
"0",
peer,
msgElements,
new Map()
);
let retMsg = data[1].find(msgRecord => {
if (msgRecord.guildId === msgId) {
return true;
}
});
return retMsg;
}
static async getMsgUniqueEx() {
let msgId = await NTQQMsgApi.getMsgUnique(await NTQQMsgApi.getServerTime());

View File

@@ -731,6 +731,7 @@ export interface MultiForwardMsgElement {
}
export interface RawMessage {
guildId: string;
msgRandom: string;
// int32, 自己维护的消息id
id?: number;

View File

@@ -62,6 +62,7 @@ export enum BuddyReqType {
KMEINITIATORWAITPEERCONFIRM
}
export interface FriendRequest {
isInitiator?: boolean;
isDecide: boolean;
friendUid: string;
reqType: BuddyReqType,

View File

@@ -5,7 +5,7 @@ import { GeneralCallResult } from '@/core/services/common';
export interface NodeIKernelMsgService {
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>;
@@ -117,7 +117,7 @@ export interface NodeIKernelMsgService {
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;
@@ -178,14 +178,14 @@ export interface NodeIKernelMsgService {
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;
getSourceOfReplyMsgByClientSeqAndTime(...args: unknown[]): unknown;
getMsgByClientSeqAndTime(peer: Peer, clientSeq: string, time: string): 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;
getMsgsByTypeFilters(peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilters: Array<{ type: number, subtype: Array<number> }>): unknown;
@@ -534,7 +534,7 @@ export interface NodeIKernelMsgService {
queryCalendar(...args: unknown[]): unknown;
queryFirstMsgSeq(...args: unknown[]): unknown;
queryFirstMsgSeq(peer: Peer, ...args: unknown[]): unknown;
queryRoamCalendar(...args: unknown[]): unknown;
@@ -628,6 +628,8 @@ export interface NodeIKernelMsgService {
// this.gameSession = tempChatGameSession;
prepareTempChat(args: unknown): unknown;//主动临时消息 不做
sendSsoCmdReqByContend(cmd: string, param: string): Promise<unknown>;
//chattype,uid->Promise<any>
getTempChatInfo(ChatType: number, Uid: string): unknown;

View File

@@ -200,8 +200,6 @@ export interface NodeIKernelRichMediaService {
getGroupFileInfo(arg1: unknown, arg2: unknown): unknown;
getGroupFileList(arg1: unknown, arg2: unknown): unknown;
getGroupTransferList(arg1: unknown, arg2: unknown): unknown;
renameGroupFile(arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): unknown;

View 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);
}
}

View File

@@ -1,15 +1,12 @@
import BaseAction from '../BaseAction';
import fs from 'fs/promises';
import { ob11Config } from '@/onebot11/config';
import { log, logDebug } from '@/common/utils/log';
import { sleep } from '@/common/utils/helper';
import { uri2local } from '@/common/utils/file';
import { UUIDConverter } from '@/common/utils/helper';
import { ActionName, BaseCheckResult } from '../types';
import { ChatType, FileElement, Peer, RawMessage, VideoElement } from '@/core/entities';
import { NTQQFileApi, NTQQMsgApi } from '@/core/apis';
import { ChatType, ElementType, FileElement, Peer, RawMessage, VideoElement } from '@/core/entities';
import { NTQQFileApi, NTQQFriendApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis';
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import Ajv from 'ajv';
import { MessageUnique } from '@/common/utils/MessageUnique';
import { getGroup } from '@/core/data';
export interface GetFilePayload {
file: string; // 文件名或者fileUuid
@@ -46,6 +43,65 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
}
protected async _handle(payload: GetFilePayload): Promise<GetFileResponse> {
const { enableLocalFile2Url } = ob11Config;
let UuidData: {
high: string;
low: string;
} | undefined;
try {
UuidData = UUIDConverter.decode(payload.file);
if (UuidData) {
let peerUin = UuidData.high;
let msgId = UuidData.low;
let isGroup = await getGroup(peerUin);
let peer: Peer | undefined;
//识别Peer
if (isGroup) {
peer = { chatType: ChatType.group, peerUid: peerUin };
}
let PeerUid = await NTQQUserApi.getUidByUin(peerUin);
if (PeerUid) {
let 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');
}
let msgList = await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]);
if (msgList.msgList.length == 0) {
throw new Error('msg not found');
}
let msg = msgList.msgList[0];
let 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');
}
let downloadPath = await NTQQFileApi.downloadMedia(msgId, msg.chatType, msg.peerUid, findEle.elementId, '', '');
let fileSize = findEle?.videoElement?.fileSize || findEle?.fileElement?.fileSize || findEle?.pttElement?.fileSize || '0';
let 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;
if (NTSearchNameResult.length !== 0) {
const MsgId = NTSearchNameResult[0].msgId;
@@ -69,7 +125,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
const res: GetFileResponse = {
file: downloadPath,
url: downloadPath,
file_size: NTSearchNameResult[0].fileSize.toString(),
file_size: NTSearchNameResult[0].fileSize.toString(),
file_name: NTSearchNameResult[0].fileName
};
if (enableLocalFile2Url) {
@@ -82,7 +138,6 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
//不手动删除?文件持久化了
return res;
}
//下面逻辑是有UUID的情况
throw new Error('file not found');
// let cache = await dbUtil.getFileCacheByName(payload.file);
// if (!cache) {

View File

@@ -77,6 +77,7 @@ import { GetProfileLike } from './extends/GetProfileLike';
import SetGroupHeader from './extends/SetGroupHeader';
import { FetchCustomFace } from './extends/FetchCustomFace';
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivareFile';
import TestApi01 from './extends/TestApi01';
export const actionHandlers = [
new RebootNormal(),
@@ -160,9 +161,9 @@ export const actionHandlers = [
new GetProfileLike(),
new SetGroupHeader(),
new FetchCustomFace(),
new GoCQHTTPUploadPrivateFile()
new GoCQHTTPUploadPrivateFile(),
new TestApi01()
];
function initActionMap() {
const actionMap = new Map<string, BaseAction<any, any>>();
for (const action of actionHandlers) {

View File

@@ -32,10 +32,18 @@ class GetMsg extends BaseAction<Payload, OB11Message> {
if (!msgIdWithPeer) {
throw ('消息不存在');
}
const peer = { guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType };
const msg = await NTQQMsgApi.getMsgsByMsgId(
{ guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType },
peer,
[msgIdWithPeer?.MsgId || payload.message_id.toString()]);
return await OB11Constructor.message(msg.msgList[0]);
let 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;
}
}

View File

@@ -12,25 +12,22 @@ import {
SignMusicWrapper
} from '@/core';
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 { ob11Config } from '@/onebot11/config';
import { RequestUtil } from '@/common/utils/request';
import fs from 'node:fs';
import { MessageUnique } from '@/common/utils/MessageUnique';
export type MessageContext = {
group?: Group,
deleteAfterSentFiles: string[],
}
async function handleOb11FileLikeMessage(
{ data: { file, name: payloadFileName } }: OB11MessageFileBase,
{ data: inputdata }: OB11MessageFileBase,
{ deleteAfterSentFiles }: MessageContext
) {
const uri = file;
const { path, isLocal, fileName, errMsg } = (await uri2local(uri));
//有的奇怪的框架将url作为参数 而不是file 此时优先url
let { path, isLocal, fileName, errMsg } = (await uri2local(inputdata?.url || inputdata.file));
if (errMsg) {
logError('文件下载失败', errMsg);
@@ -41,7 +38,7 @@ async function handleOb11FileLikeMessage(
deleteAfterSentFiles.push(path);
}
return { path, fileName: payloadFileName || fileName };
return { path, fileName: inputdata.name || fileName };
}
const _handlers: {

View File

@@ -101,5 +101,6 @@ export enum ActionName {
GetProfileLike = 'get_profile_like',
SetGroupHeader = 'set_group_head',
FetchCustomFace = 'fetch_custom_face',
GOCQHTTP_UploadPrivateFile = 'upload_private_file'
GOCQHTTP_UploadPrivateFile = 'upload_private_file',
TestApi01 = "test_api_01"
}

View File

@@ -35,7 +35,7 @@ import { OB11GroupNoticeEvent } from './event/notice/OB11GroupNoticeEvent';
import { calcQQLevel } from '../common/utils/qqlevel';
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 { OB11GroupCardEvent } from './event/notice/OB11GroupCardEvent';
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 { OB11GroupMsgEmojiLikeEvent } from '@/onebot11/event/notice/OB11MsgEmojiLikeEvent';
import { OB11FriendPokeEvent, OB11GroupPokeEvent } from './event/notice/OB11PokeEvent';
import { OB11FriendAddNoticeEvent } from './event/notice/OB11FriendAddNoticeEvent';
import { OB11BaseNoticeEvent } from './event/notice/OB11BaseNoticeEvent';
import { OB11GroupEssenceEvent } from './event/notice/OB11GroupEssenceEvent';
import { MessageUnique } from '@/common/utils/MessageUnique';
@@ -173,6 +174,7 @@ export class OB11Constructor {
// message_data["data"]["file"] = element.picElement.sourcePath
message_data['data']['file'] = element.picElement.fileName;
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
try {
@@ -185,13 +187,12 @@ export class OB11Constructor {
message_data['data']['file_size'] = element.picElement.fileSize;
}
else if (element.fileElement) {
const FileElement = element.fileElement;
message_data['type'] = OB11MessageDataType.file;
message_data['data']['file'] = FileElement.fileName;
message_data['data']['path'] = 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;
await NTQQFileApi.addFileCache({
peerUid: msg.peerUid,
@@ -237,7 +238,7 @@ export class OB11Constructor {
message_data['data']['file'] = videoElement.fileName;
message_data['data']['path'] = 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;
await NTQQFileApi.addFileCache({
@@ -258,19 +259,9 @@ export class OB11Constructor {
message_data['type'] = OB11MessageDataType.voice;
message_data['data']['file'] = element.pttElement.fileName;
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;
// 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({
peerUid: msg.peerUid,
chatType: msg.chatType,
@@ -350,6 +341,7 @@ export class OB11Constructor {
if (element.grayTipElement) {
if (element.grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE) {
const json = JSON.parse(element.grayTipElement.jsonGrayTipElement.jsonStr);
if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) {
//判断业务类型
//Poke事件
@@ -358,11 +350,17 @@ export class OB11Constructor {
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));
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
}
if (element.grayTipElement.subElementType == GrayTipElementSubType.INVITE_NEW_MEMBER) {
//好友添加成功事件
if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') {
return new OB11FriendAddNoticeEvent(parseInt(msg.peerUin));
}
}
}
}
}

View 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;
}
}

View File

@@ -10,22 +10,25 @@ class OB11PokeEvent extends OB11BaseNoticeEvent {
}
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();
this.target_id = target_id;
this.user_id = user_id;
this.raw_info = raw_message;
}
}
export class OB11GroupPokeEvent extends OB11PokeEvent {
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) {
super();
this.group_id = group_id;
this.target_id = target_id;
this.user_id = user_id;
this.raw_message = raw_message;
this.raw_info = raw_message;
}
}

View File

@@ -241,20 +241,20 @@ export class NapCatOnebot11 {
msgListener.onMsgInfoListUpdate = (msgList) => {
this.postRecallMsg(msgList).then().catch(logError);
for (const msg of msgList.filter(e => e.senderUin == selfInfo.uin)) {
// console.log(msg);
if (msg.sendStatus !== 2) {
// console.log(msg);
if (msg.sendStatus == 2) {
//完成后再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) => {
@@ -285,7 +285,7 @@ export class NapCatOnebot11 {
// }
groupListener.onGroupNotifiesUpdated = async (doubt, notifies) => {
//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));
}
};
@@ -594,7 +594,7 @@ export class NapCatOnebot11 {
async postFriendRequest(reqs: FriendRequest[]) {
for (const req of reqs) {
if (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM) {
if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM)) {
continue;
}
const friendRequestEvent = new OB11FriendRequestEvent();

View File

@@ -1 +1 @@
export const version = '1.7.2';
export const version = '1.7.4';

View File

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

View File

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