From 8f54310f63e1cbead4bdcb600231c8e58c3c876d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Sun, 28 Jul 2024 23:35:58 +0800 Subject: [PATCH] refactor: reply --- src/common/utils/MessageUnique.ts | 25 ++++++++++++++++-- src/core/src/apis/user.ts | 27 +++++++------------ src/onebot11/constructor.ts | 44 ++++++++++++++++++++----------- 3 files changed, 62 insertions(+), 34 deletions(-) diff --git a/src/common/utils/MessageUnique.ts b/src/common/utils/MessageUnique.ts index 430ec621..162bcedb 100644 --- a/src/common/utils/MessageUnique.ts +++ b/src/common/utils/MessageUnique.ts @@ -65,6 +65,19 @@ class LimitedHashTable { getKeyList(): K[] { return Array.from(this.keyToValue.keys()); } + //获取最近刚写入的几个值 + getHeads(size: number): { key: K; value: V }[] | undefined { + const keyList = this.getKeyList(); + if (keyList.length === 0) { + return undefined; + } + const result: { key: K; value: V }[] = []; + for (let i = 0; i < Math.min(size, keyList.length); i++) { + const key = keyList[i]; + result.push({ key, value: this.keyToValue.get(key)! }); + } + return result; + } } class MessageUniqueWrapper { @@ -74,11 +87,19 @@ class MessageUniqueWrapper { this.msgIdMap = new LimitedHashTable(maxMap); this.msgDataMap = new LimitedHashTable(maxMap); } - + getRecentMsgIds(Peer: Peer, size: number): string[] { + const heads = this.msgIdMap.getHeads(size); + if (!heads) { + return []; + } + let date = heads.map((t) => MessageUnique.getMsgIdAndPeerByShortId(t.value)); + let ret = date.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid); + return ret.map((t) => t?.MsgId).filter((t) => t !== undefined); + } createMsg(peer: Peer, msgId: string): number | undefined { const key = `${msgId}|${peer.chatType}|${peer.peerUid}`; const hash = crypto.createHash('sha1').update(key); - const shortId = Buffer.from(hash.digest('hex').slice(0, 8),'hex').readInt32BE(); + const shortId = Buffer.from(hash.digest('hex').slice(0, 8), 'hex').readInt32BE(); const isExist = this.msgIdMap.getKey(shortId); //console.log(`${peer.peerUid} ${msgId} ------- ${shortId}`); if (isExist && isExist === msgId) { diff --git a/src/core/src/apis/user.ts b/src/core/src/apis/user.ts index 1ac6e5d1..9ed263ed 100644 --- a/src/core/src/apis/user.ts +++ b/src/core/src/apis/user.ts @@ -143,39 +143,32 @@ export class NTQQUserApi { return false; }) static async getUidByUin(Uin: string) { + //Uid 接口转 let ret = await NTEventDispatch.CallNoListenerEvent <(Uin: string[]) => Promise<{ uidInfo: Map }>>( 'NodeIKernelUixConvertService/getUid', 5000, [Uin] ); - let uid = ret.uidInfo.get(Uin); //通过QQ默认方式转换 + let uid = ret.uidInfo.get(Uin); + // Uid 好友转 if (!uid) { Array.from(friends.values()).forEach((t) => { if (t.uin == Uin) { - //logDebug('getUidByUin', t.uid, t.uin, Uin); uid = t.uid; } - //console.log(t.uid, t.uin, Uin); }); - //缓解措施 从群里取 - if (!uid) { - for (let groupMembersList of groupMembers.values()) { - let data = groupMembersList.get(Uin); - if (data?.uid) { - uid = data.uid; + } + //Uid 群友列表转 + if (!uid) { + for (let groupMembersList of groupMembers.values()) { + for (let GroupMember of groupMembersList.values()) { + if (GroupMember.uin == Uin) { + uid = GroupMember.uid; } } } - //uid = Array.from(friends.values()).find((t) => { t.uin == Uin })?.uid; // 从NC维护的QQ Buddy缓存 转换 } - - // if (!uid) { - // uid = (await NTQQFriendApi.getFriends(false)).find((t) => { t.uin == Uin })?.uid; //从QQ Native 缓存转换 方法一 - // } - // if (!uid) { - // uid = (await NTQQFriendApi.getFriends(true)).find((t) => { t.uin == Uin })?.uid; //从QQ Native 非缓存转换 方法二 - // } if (!uid) { let unveifyUid = (await NTQQUserApi.getUserDetailInfoByUin(Uin)).info.uid;//从QQ Native 特殊转换 方法三 if (unveifyUid.indexOf("*") == -1) { diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts index 5f9d6cd4..7a546b28 100644 --- a/src/onebot11/constructor.ts +++ b/src/onebot11/constructor.ts @@ -34,7 +34,7 @@ import { OB11GroupUploadNoticeEvent } from './event/notice/OB11GroupUploadNotice import { OB11GroupNoticeEvent } from './event/notice/OB11GroupNoticeEvent'; import { calcQQLevel } from '../common/utils/qqlevel'; -import { log, logDebug, logError } from '../common/utils/log'; +import { log, logDebug, logError, logWarn } from '../common/utils/log'; import { sleep } from '../common/utils/helper'; import { OB11GroupTitleEvent } from './event/notice/OB11GroupTitleEvent'; import { OB11GroupCardEvent } from './event/notice/OB11GroupCardEvent'; @@ -142,23 +142,37 @@ export class OB11Constructor { if (!records) { throw new Error('Record筛选失败'); } - let replyMsg = await NTQQMsgApi.queryMsgsWithFilterExWithSeq( - { - chatType: msg.chatType, - peerUid: msg.peerUid, - guildId: '', - }, - element.replyElement.replayMsgSeq, - records.msgTime, - records.senderUid - ); - if (replyMsg.msgList.length === 0 || replyMsg.msgList[0].msgRandom !== records.msgRandom) { - await sleep(300); - replyMsg = await NTQQMsgApi.getMsgsBySeqAndCount({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, element.replyElement.replayMsgSeq, 1, true, true); + let peer = { + chatType: msg.chatType, + peerUid: msg.peerUid, + guildId: '', + }; + let replyMsg: RawMessage | undefined; + replyMsg = (await NTQQMsgApi.getMsgsByMsgId(peer, MessageUnique.getRecentMsgIds(peer, 50))).msgList.find((msg) => msg.msgRandom == records.msgRandom && msg.msgSeq == element.replyElement.replayMsgSeq); + + + if (!replyMsg || replyMsg.msgRandom !== records.msgRandom) { + logWarn(`消息比对失败,准备重新尝试 Info: CurrentMsgRandom:${replyMsg?.msgRandom}/TargetMsgRandom:${records.msgRandom}`); + await sleep(500); + replyMsg = (await NTQQMsgApi.queryMsgsWithFilterExWithSeq( + peer, + element.replyElement.replayMsgSeq, + records.msgTime, + records.senderUid + )).msgList[0]; } + if (!replyMsg || replyMsg.msgRandom !== records.msgRandom) { + logWarn(`消息比对失败,准备重新尝试 Info: CurrentMsgRandom:${replyMsg?.msgRandom}/TargetMsgRandom:${records.msgRandom}`); + await sleep(500); + replyMsg = (await NTQQMsgApi.getMsgsBySeqAndCount({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, element.replyElement.replayMsgSeq, 1, true, true)).msgList[0]; + } + if (!replyMsg || replyMsg.msgRandom !== records.msgRandom) { + logWarn(`消息比对失败,准备重新尝试 Info: CurrentMsgRandom:${replyMsg?.msgRandom}/TargetMsgRandom:${records.msgRandom}`); + throw new Error('回复消息消息验证失败') + } if (replyMsg) { - message_data['data']['id'] = MessageUnique.createMsg({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, replyMsg.msgList[0].msgId)?.toString(); + message_data['data']['id'] = MessageUnique.createMsg({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, replyMsg.msgId)?.toString(); } else { continue;