diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/MsgSvc.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/MsgSvc.kt index e0bbbd6..6672f14 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/MsgSvc.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/MsgSvc.kt @@ -50,6 +50,36 @@ internal object MsgSvc: BaseSvc() { } } + suspend fun getMsgByQMsgId( + chatType: Int, + peerId: String, + qqMsgId: Long + ): Result { + val contact = MessageHelper.generateContact(chatType, peerId) + + val msg = withTimeoutOrNull(5000) { + val service = QRoute.api(IMsgService::class.java) + suspendCancellableCoroutine { continuation -> + service.getMsgsByMsgId(contact, arrayListOf(qqMsgId)) { code, _, msgRecords -> + if (code == 0 && msgRecords.isNotEmpty()) { + continuation.resume(msgRecords.first()) + } else { + continuation.resume(null) + } + } + continuation.invokeOnCancellation { + continuation.resume(null) + } + } + } + + return if (msg != null) { + Result.success(msg) + } else { + Result.failure(Exception("获取消息失败")) + } + } + /** * 什么鸟屎都获取不到 */ @@ -59,7 +89,7 @@ internal object MsgSvc: BaseSvc() { seq: Long ): Result { val contact = MessageHelper.generateContact(chatType, peerId) - val msg = withTimeoutOrNull(60 * 1000) { + val msg = withTimeoutOrNull(1000) { val service = QRoute.api(IMsgService::class.java) suspendCancellableCoroutine { continuation -> service.getMsgsBySeqs(contact, arrayListOf(seq)) { code, _, msgRecords -> diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/convert/MessageElemConverter.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/convert/MessageElemConverter.kt index 582ee7b..ed3922f 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/convert/MessageElemConverter.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/convert/MessageElemConverter.kt @@ -2,6 +2,7 @@ package moe.fuqiuluo.qqinterface.servlet.msg.convert import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgElement +import moe.fuqiuluo.qqinterface.servlet.MsgSvc import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc import moe.fuqiuluo.shamrock.helper.ContactHelper import moe.fuqiuluo.shamrock.helper.Level @@ -252,7 +253,11 @@ internal sealed class MessageElemConverter: IMessageConvert { } else { MessageDB.getInstance().messageMappingDao() .queryByMsgSeq(chatType, peerId, reply.replayMsgSeq?.toInt() ?: 0)?.msgHashId - ?: MessageHelper.generateMsgIdHash(chatType, reply.sourceMsgIdInRecords) + ?: + kotlin.run { + LogCenter.log("消息映射关系未找到: Message($reply)", Level.WARN) + MessageHelper.generateMsgIdHash(chatType, reply.sourceMsgIdInRecords) + } } return MessageSegment( diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/AioListener.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/AioListener.kt index be86288..f37697d 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/AioListener.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/AioListener.kt @@ -5,7 +5,9 @@ import moe.fuqiuluo.shamrock.helper.MessageHelper import com.tencent.qqnt.kernel.nativeinterface.* import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import moe.fuqiuluo.qqinterface.servlet.MsgSvc import moe.fuqiuluo.qqinterface.servlet.msg.convert.toCQCode import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig @@ -16,6 +18,8 @@ import moe.fuqiuluo.shamrock.remote.service.data.push.MessageTempSource import moe.fuqiuluo.shamrock.remote.service.data.push.PostType import java.util.ArrayList import java.util.HashMap +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine internal object AioListener: IKernelMsgListener { override fun onRecvMsg(msgList: ArrayList) { @@ -97,10 +101,28 @@ internal object AioListener: IKernelMsgListener { } } - override fun onAddSendMsg(record: MsgRecord) { + override fun onAddSendMsg(tmpRecord: MsgRecord) { GlobalScope.launch { try { - val msgHash = MessageHelper.generateMsgIdHash(record.chatType, record.msgId) + val msgHash = MessageHelper.generateMsgIdHash(tmpRecord.chatType, tmpRecord.msgId) + + val record = suspendCoroutine { + GlobalScope.launch { + while (true) { + MsgSvc.getMsgByQMsgId(tmpRecord.chatType, tmpRecord.peerUin.toString(), tmpRecord.msgId).onSuccess { record -> + if (record.sendStatus == MsgConstant.KSENDSTATUSSUCCESS || + record.sendStatus == MsgConstant.KSENDSTATUSSUCCESSNOSEQ + ) { + it.resume(record) + } else if (record.sendStatus == MsgConstant.KSENDSTATUSFAILED) { + it.resume(null) + } + } + delay(50) + } + } + } ?: return@launch + MessageHelper.saveMsgMapping( hash = msgHash, qqMsgId = record.msgId, @@ -114,7 +136,7 @@ internal object AioListener: IKernelMsgListener { val rawMsg = record.elements.toCQCode(record.chatType, record.peerUin.toString()) if (rawMsg.isEmpty()) return@launch - LogCenter.log("发送消息($msgHash|${record.msgSeq}): $rawMsg") + LogCenter.log("发送消息($msgHash | ${record.msgSeq} | ${record.msgId}): $rawMsg") if (!ShamrockConfig.enableSelfMsg()) return@launch diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/PrimitiveListener.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/PrimitiveListener.kt index ff9a2c1..26c8d24 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/PrimitiveListener.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/listener/PrimitiveListener.kt @@ -247,13 +247,12 @@ internal object PrimitiveListener { val tipText = if (detail.has(11, 9)) detail[11, 9, 2].asUtf8String else "" val mapping = MessageHelper.getMsgMappingBySeq(MsgConstant.KCHATTYPEGROUP, msgSeq.toInt()) if (mapping == null) { - LogCenter.log("由于缺失消息映射关系,消息撤回事件无法推送!", Level.WARN) + LogCenter.log("由于缺失消息映射关系(seq = $msgSeq),消息撤回事件无法推送!", Level.WARN) return } val msgHash = mapping.msgHashId val operator = ContactHelper.getUinByUidAsync(operatorUid).toLong() val target = ContactHelper.getUinByUidAsync(targetUid).toLong() - LogCenter.log("群消息撤回($groupCode): $operator -> $target, seq = $msgSeq, hash = $msgHash, tip = $tipText") if(!GlobalEventTransmitter.GroupNoticeTransmitter