From 9faa56ec324e32f20630cb7dbdf00106182a8e7a Mon Sep 17 00:00:00 2001 From: linyuchen Date: Tue, 27 Feb 2024 19:47:17 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=BB=9F=E4=B8=80=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E6=88=B3=E4=B8=BA=E6=AF=AB=E7=A7=92=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=8F=91=E9=80=81=E6=B6=88=E6=81=AF=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20fix:=20=E5=8F=91=E9=80=81=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E6=96=87=E4=BB=B6=E5=90=8D=E4=BF=9D=E6=8C=81?= =?UTF-8?q?=E5=8E=9F=E6=A0=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 + src/ntqqapi/constructor.ts | 22 +++-- src/ntqqapi/ntcall.ts | 130 +++++++++++++--------------- src/onebot11/action/SendMsg.ts | 2 +- src/onebot11/constructor.ts | 2 +- src/onebot11/event/OB11BaseEvent.ts | 2 +- src/onebot11/utils.ts | 9 +- 7 files changed, 89 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 1fc4752..1cf5a74 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,8 @@ TG群: - [x] 处理添加好友请求 - [x] 处理加群请求 - [x] 退群 +- [ ] 上报加群邀请 +- [ ] 同意加群邀请 - [x] 上报好友消息 - [x] 上报添加好友请求 - [x] 上报群消息 @@ -159,6 +161,8 @@ TG群: - [x] 群管理功能,禁言、踢人,改群名片等 - [x] 视频消息 - [x] 文件消息 +- [ ] 上报加群邀请 +- [ ] 同意加群邀请 - [ ] 音乐卡片 - [ ] 无头模式 diff --git a/src/ntqqapi/constructor.ts b/src/ntqqapi/constructor.ts index 12611c7..0187bb6 100644 --- a/src/ntqqapi/constructor.ts +++ b/src/ntqqapi/constructor.ts @@ -9,7 +9,7 @@ import { SendTextElement } from "./types"; import {NTQQApi} from "./ntcall"; -import {encodeSilk, log} from "../common/utils"; +import {encodeSilk} from "../common/utils"; import fs from "fs"; @@ -56,7 +56,7 @@ export class SendMsgElementConstructor { } static async pic(picPath: string): Promise { - const {md5, fileName, path, fileSize} = await NTQQApi.uploadFile(picPath); + const {md5, fileName, path, fileSize} = await NTQQApi.uploadFile(picPath, ElementType.PIC); const imageSize = await NTQQApi.getImageSize(picPath); const picElement = { md5HexStr: md5, @@ -81,8 +81,14 @@ export class SendMsgElementConstructor { }; } - static async file(filePath: string, isVideo:boolean = false): Promise { - const {md5, fileName, path, fileSize} = await NTQQApi.uploadFile(filePath); + static async file(filePath: string, isVideo: boolean = false): Promise { + let picHeight = 0; + let picWidth = 0; + if (isVideo) { + picHeight = 1024; + picWidth = 768; + } + const {md5, fileName, path, fileSize} = await NTQQApi.uploadFile(filePath, ElementType.FILE); let element: SendFileElement = { elementType: ElementType.FILE, elementId: "", @@ -90,18 +96,18 @@ export class SendMsgElementConstructor { fileName, "filePath": path, "fileSize": (fileSize).toString(), + picHeight, + picWidth } } - if (isVideo){ - element.fileElement.picHeight = 1024; - element.fileElement.picWidth = 768; - } + return element; } static video(filePath: string): Promise { return SendMsgElementConstructor.file(filePath, true); } + static async ptt(pttPath: string): Promise { const {converted, path: silkPath, duration} = await encodeSilk(pttPath); // log("生成语音", silkPath, duration); diff --git a/src/ntqqapi/ntcall.ts b/src/ntqqapi/ntcall.ts index 65fee84..09d9142 100644 --- a/src/ntqqapi/ntcall.ts +++ b/src/ntqqapi/ntcall.ts @@ -1,13 +1,14 @@ import {ipcMain} from "electron"; import {hookApiCallbacks, ReceiveCmd, registerReceiveHook, removeReceiveHook} from "./hook"; -import {log} from "../common/utils"; +import {log, sleep} from "../common/utils"; import { ChatType, ElementType, Friend, FriendRequest, Group, - GroupMember, GroupMemberRole, + GroupMember, + GroupMemberRole, GroupNotifies, GroupNotify, GroupRequestOperateTypes, @@ -19,6 +20,7 @@ import { import * as fs from "fs"; import {addHistoryMsg, friendRequests, groupNotifies, msgHistory, selfInfo} from "../common/data"; import {v4 as uuidv4} from "uuid" +import path from "path"; interface IPCReceiveEvent { eventName: string @@ -346,7 +348,10 @@ export class NTQQApi { } else { ext = "" } - const fileName = `${md5}${ext}`; + let fileName = `${path.basename(filePath)}`; + if (fileName.indexOf(".") === -1) { + fileName += ext; + } const mediaPath = await callNTQQApi({ methodName: NTQQApiMethod.MEDIA_FILE_PATH, args: [{ @@ -414,71 +419,57 @@ export class NTQQApi { }) } - static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = false, timeout = 10000) { - const sendTimeout = timeout + static async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = false, timeout = 10000) { + const peerUid = peer.peerUid; - return new Promise((resolve, reject) => { - const peerUid = peer.peerUid; - let usingTime = 0; - let success = false; - let isTimeout = false; - - const checkSuccess = () => { - if (!success) { - sendMessagePool[peerUid] = null; - isTimeout = true; - reject("发送超时") - } + // 等待上一个相同的peer发送完 + let checkLastSendUsingTime = 0; + const waitLastSend = async () => { + if (checkLastSendUsingTime > timeout) { + throw ("发送超时") } - setTimeout(checkSuccess, sendTimeout); - - const checkLastSend = () => { - let lastSending = sendMessagePool[peerUid] - if (sendTimeout < usingTime) { - sendMessagePool[peerUid] = null; - isTimeout = true; - reject("发送超时") - } - if (!!lastSending) { - // log("有正在发送的消息,等待中...") - usingTime += 500; - setTimeout(checkLastSend, 500); - } else { - log("可以进行发送消息,设置发送成功回调", sendMessagePool) - sendMessagePool[peerUid] = (rawMessage: RawMessage) => { - sendMessagePool[peerUid] = null; - const checkSendComplete = () => { - if (isTimeout) { - return reject("发送超时") - } - if (msgHistory[rawMessage.msgId]?.sendStatus == 2) { - log(`给${peerUid}发送消息成功`) - success = true; - resolve(rawMessage); - } else { - setTimeout(checkSendComplete, 500) - } - } - if (waitComplete) { - checkSendComplete(); - } else { - success = true; - log(`给${peerUid}发送消息成功`) - resolve(rawMessage); - } - } - } + let lastSending = sendMessagePool[peer.peerUid] + if (lastSending) { + // log("有正在发送的消息,等待中...") + await sleep(500); + checkLastSendUsingTime += 500; + return await waitLastSend(); + } else { + return; } - checkLastSend() - callNTQQApi({ - methodName: NTQQApiMethod.SEND_MSG, - args: [{ - msgId: "0", - peer, msgElements, - msgAttributeInfos: new Map(), - }, null] - }).then() - }) + } + await waitLastSend(); + + let sentMessage: RawMessage = null; + sendMessagePool[peerUid] = async (rawMessage: RawMessage) => { + delete sendMessagePool[peerUid]; + sentMessage = rawMessage; + } + + let checkSendCompleteUsingTime = 0; + const checkSendComplete = async (): Promise => { + if (sentMessage && msgHistory[sentMessage.msgId]?.sendStatus == 2) { + // log(`给${peerUid}发送消息成功`) + return sentMessage; + } else { + checkSendCompleteUsingTime += 500; + if (checkSendCompleteUsingTime > timeout) { + throw ("发送超时") + } + await sleep(500); + return await checkSendComplete() + } + } + + callNTQQApi({ + methodName: NTQQApiMethod.SEND_MSG, + args: [{ + msgId: "0", + peer, msgElements, + msgAttributeInfos: new Map(), + }, null] + }).then() + return checkSendComplete(); } static multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]) { @@ -638,7 +629,8 @@ export class NTQQApi { } ) } - static banGroup(groupQQ: string, shutUp: boolean){ + + static banGroup(groupQQ: string, shutUp: boolean) { return callNTQQApi({ methodName: NTQQApiMethod.MUTE_GROUP, args: [ @@ -676,14 +668,14 @@ export class NTQQApi { }) } - static setGroupName(groupQQ: string, groupName: string){ + static setGroupName(groupQQ: string, groupName: string) { return callNTQQApi({ methodName: NTQQApiMethod.SET_GROUP_NAME, - args:[ + args: [ { groupCode: groupQQ, groupName - },null + }, null ] }) } diff --git a/src/onebot11/action/SendMsg.ts b/src/onebot11/action/SendMsg.ts index 74d82cb..86dde3d 100644 --- a/src/onebot11/action/SendMsg.ts +++ b/src/onebot11/action/SendMsg.ts @@ -236,7 +236,7 @@ export class SendMsg extends BaseAction { case OB11MessageDataType.voice: { const file = sendMsg.data?.file if (file) { - const {path, isLocal} = (await uri2local(uuidv4(), file)) + const {path, isLocal} = (await uri2local(file)) if (path) { if (!isLocal) { // 只删除http和base64转过来的文件 deleteAfterSentFiles.push(path) diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts index 2c49a89..0616842 100644 --- a/src/onebot11/constructor.ts +++ b/src/onebot11/constructor.ts @@ -23,7 +23,7 @@ export class OB11Constructor { const resMsg: OB11Message = { self_id: parseInt(selfInfo.uin), user_id: parseInt(msg.senderUin), - time: parseInt(msg.msgTime) || 0, + time: parseInt(msg.msgTime) * 1000 || Date.now(), // 13位时间戳,毫秒 message_id: msg.msgShortId, real_id: msg.msgId, message_type: msg.chatType == ChatType.group ? "group" : "private", diff --git a/src/onebot11/event/OB11BaseEvent.ts b/src/onebot11/event/OB11BaseEvent.ts index a495d1d..af636d1 100644 --- a/src/onebot11/event/OB11BaseEvent.ts +++ b/src/onebot11/event/OB11BaseEvent.ts @@ -10,7 +10,7 @@ export enum EventType { export abstract class OB11BaseEvent { - time = new Date().getTime(); + time = Date.now(); self_id = parseInt(selfInfo.uin); post_type: EventType; } \ No newline at end of file diff --git a/src/onebot11/utils.ts b/src/onebot11/utils.ts index a63e551..b7966f8 100644 --- a/src/onebot11/utils.ts +++ b/src/onebot11/utils.ts @@ -1,10 +1,13 @@ import {CONFIG_DIR, isGIF} from "../common/utils"; +import {v4 as uuidv4} from "uuid"; import * as path from 'path'; -import {OB11MessageData} from "./types"; const fs = require("fs").promises; -export async function uri2local(fileName: string, uri: string){ +export async function uri2local(uri: string, fileName: string=null){ + if (!fileName){ + fileName = uuidv4(); + } let filePath = path.join(CONFIG_DIR, fileName) let url = new URL(uri); let res = { @@ -33,6 +36,8 @@ export async function uri2local(fileName: string, uri: string){ let blob = await fetchRes.blob(); let buffer = await blob.arrayBuffer(); try { + fileName = path.basename(url.pathname) || fileName + filePath = path.join(CONFIG_DIR, fileName) await fs.writeFile(filePath, Buffer.from(buffer)); } catch (e: any) { res.errMsg = `${url}下载失败,` + e.toString()