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 dda28d8..ababfd3 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 @@ -327,10 +327,10 @@ internal sealed class MessageElemConverter: IMessageConvert { val fileSize = fileMsg.fileSize val expireTime = fileMsg.expireTime ?: 0 val fileId = fileMsg.fileUuid - val bizId = fileMsg.fileBizId + val bizId = fileMsg.fileBizId ?: 0 val fileSubId = fileMsg.fileSubId ?: "" val url = if (chatType == MsgConstant.KCHATTYPEC2C) RichProtoSvc.getC2CFileDownUrl(fileId, fileSubId) - else RichProtoSvc.getGroupFileDownUrl(peerId.toLong(), fileId, fileMsg.fileBizId) + else RichProtoSvc.getGroupFileDownUrl(peerId.toLong(), fileId, bizId) return MessageSegment( type = "file", diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/UploadGroupFile.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/UploadGroupFile.kt index 044e727..0764880 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/UploadGroupFile.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/UploadGroupFile.kt @@ -5,12 +5,15 @@ import android.graphics.BitmapFactory import android.media.MediaMetadataRetriever import com.tencent.mobileqq.qroute.QRoute import com.tencent.qqnt.kernel.nativeinterface.FileElement +import com.tencent.qqnt.kernel.nativeinterface.FileTransNotifyInfo import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgElement import com.tencent.qqnt.msg.api.IMsgService import com.tencent.qqnt.msg.api.IMsgUtilApi import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext +import kotlinx.coroutines.withTimeoutOrNull import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonElement @@ -19,11 +22,13 @@ import moe.fuqiuluo.shamrock.helper.MessageHelper import moe.fuqiuluo.shamrock.helper.TransfileHelper import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.IActionHandler +import moe.fuqiuluo.shamrock.remote.service.api.RichMediaUploadHandler import moe.fuqiuluo.shamrock.tools.EmptyJsonString import moe.fuqiuluo.shamrock.utils.FileUtils import moe.fuqiuluo.shamrock.utils.MD5 import java.io.File import java.io.FileOutputStream +import kotlin.coroutines.resume internal object UploadGroupFile : IActionHandler() { override suspend fun internalHandle(session: ActionSession): String { @@ -94,16 +99,36 @@ internal object UploadGroupFile : IActionHandler() { msgElement.elementType = MsgConstant.KELEMTYPEFILE msgElement.fileElement = fileElement + // 根据文件大小调整超时时间 val msgIdPair = MessageHelper.generateMsgId(MsgConstant.KCHATTYPEGROUP) - val msgService = QRoute.api(IMsgService::class.java) - msgService.sendMsgWithMsgId( - MessageHelper.generateContact(MsgConstant.KCHATTYPEGROUP, groupId), msgIdPair.second, arrayListOf(msgElement) - ) { code, reason -> - LogCenter.log("群文件消息发送异常(code = $code, reason = $reason)") - } + val info = (withTimeoutOrNull((srcFile.length() / (300 * 1024)) * 1000 + 5000) { + val msgService = QRoute.api(IMsgService::class.java) + val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEGROUP, groupId) + suspendCancellableCoroutine { + msgService.sendMsgWithMsgId( + contact, msgIdPair.second, arrayListOf(msgElement) + ) { code, reason -> + LogCenter.log("群文件消息发送异常(code = $code, reason = $reason)") + it.resume(null) + } + RichMediaUploadHandler.registerListener(msgIdPair.second) { + it.resume(this) + return@registerListener true + } + } + } ?: return error("上传文件失败", echo)).also { + if (it.commonFileInfo == null) { + return error(it.fileErrMsg ?: "上传文件失败", echo) + } + }.commonFileInfo return ok(data = FileUploadResult( - msgHash = msgIdPair.first + msgHash = msgIdPair.first, + bizid = info.bizType ?: 0, + md5 = info.md5, + sha = info.sha, + sha3 = info.sha3, + fileId = info.uuid ), echo = echo) } @@ -114,5 +139,10 @@ internal object UploadGroupFile : IActionHandler() { @Serializable data class FileUploadResult( @SerialName("msg_id") val msgHash: Int, + @SerialName("bizid") val bizid: Int, + @SerialName("md5") val md5: String, + @SerialName("sha") val sha: String, + @SerialName("sha3") val sha3: String, + @SerialName("file_id") val fileId: String ) } \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/UploadPrivateFile.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/UploadPrivateFile.kt index 4ed2726..425b4d3 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/UploadPrivateFile.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/UploadPrivateFile.kt @@ -5,12 +5,15 @@ import android.graphics.BitmapFactory import android.media.MediaMetadataRetriever import com.tencent.mobileqq.qroute.QRoute import com.tencent.qqnt.kernel.nativeinterface.FileElement +import com.tencent.qqnt.kernel.nativeinterface.FileTransNotifyInfo import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgElement import com.tencent.qqnt.msg.api.IMsgService import com.tencent.qqnt.msg.api.IMsgUtilApi import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext +import kotlinx.coroutines.withTimeoutOrNull import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonElement @@ -20,11 +23,13 @@ import moe.fuqiuluo.shamrock.helper.MessageHelper import moe.fuqiuluo.shamrock.helper.TransfileHelper import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.IActionHandler +import moe.fuqiuluo.shamrock.remote.service.api.RichMediaUploadHandler import moe.fuqiuluo.shamrock.tools.EmptyJsonString import moe.fuqiuluo.shamrock.utils.FileUtils import moe.fuqiuluo.shamrock.utils.MD5 import java.io.File import java.io.FileOutputStream +import kotlin.coroutines.resume internal object UploadPrivateFile : IActionHandler() { override suspend fun internalHandle(session: ActionSession): String { @@ -95,26 +100,40 @@ internal object UploadPrivateFile : IActionHandler() { msgElement.elementType = MsgConstant.KELEMTYPEFILE msgElement.fileElement = fileElement + // 根据文件大小调整超时时间 val msgIdPair = MessageHelper.generateMsgId(MsgConstant.KCHATTYPEC2C) - val msgService = QRoute.api(IMsgService::class.java) - msgService.sendMsgWithMsgId( - MessageHelper.generateContact(MsgConstant.KCHATTYPEC2C, userId), msgIdPair.second, arrayListOf(msgElement) - ) { code, reason -> - if (code != 0) - LogCenter.log("私聊文件消息发送异常(code = $code, reason = $reason)") - } + val info = (withTimeoutOrNull((srcFile.length() / (300 * 1024)) * 1000 + 5000) { + val msgService = QRoute.api(IMsgService::class.java) + val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEC2C, userId) + suspendCancellableCoroutine { + msgService.sendMsgWithMsgId( + contact, msgIdPair.second, arrayListOf(msgElement) + ) { code, reason -> + LogCenter.log("私聊文件消息发送异常(code = $code, reason = $reason)") + it.resume(null) + } + RichMediaUploadHandler.registerListener(msgIdPair.second) { + it.resume(this) + return@registerListener true + } + } + } ?: return error("上传文件失败", echo)).also { + if (it.commonFileInfo == null) { + return error(it.fileErrMsg ?: "上传文件失败", echo) + } + }.commonFileInfo - return ok(data = FileUploadResult( - msgHash = msgIdPair.first + return ok(data = UploadGroupFile.FileUploadResult( + msgHash = msgIdPair.first, + bizid = info.bizType ?: 0, + md5 = info.md5, + sha = info.sha, + sha3 = info.sha3, + fileId = info.uuid ), echo = echo) } override val requiredParams: Array = arrayOf("user_id", "file", "name") override fun path(): String = "upload_private_file" - - @Serializable - data class FileUploadResult( - @SerialName("msg_id") val msgHash: Int, - ) } \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/RichMediaUploadHandler.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/RichMediaUploadHandler.kt new file mode 100644 index 0000000..196e5ff --- /dev/null +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/RichMediaUploadHandler.kt @@ -0,0 +1,27 @@ +package moe.fuqiuluo.shamrock.remote.service.api + +import com.tencent.qqnt.kernel.nativeinterface.FileTransNotifyInfo + +internal object RichMediaUploadHandler { + private val listeners by lazy { + mutableMapOf Boolean>() + } + + fun registerListener(key: Long, value: FileTransNotifyInfo.() -> Boolean) { + listeners[key] = value + } + + fun removeListener(key: Long) { + listeners.remove(key) + } + + fun notify(info: FileTransNotifyInfo): Boolean { + listeners[info.msgId]?.let { + if (it(info)) { + listeners.remove(info.msgId) + return true + } + } + return false + } +} \ No newline at end of file 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 079ed78..62dc7b7 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 @@ -15,6 +15,7 @@ import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.helper.db.MessageDB import moe.fuqiuluo.shamrock.remote.service.api.GlobalEventTransmitter +import moe.fuqiuluo.shamrock.remote.service.api.RichMediaUploadHandler import moe.fuqiuluo.shamrock.remote.service.data.push.MessageTempSource import moe.fuqiuluo.shamrock.remote.service.data.push.PostType import mqq.app.MobileQQ @@ -347,6 +348,11 @@ internal object AioListener: IKernelMsgListener { } } + override fun onRichMediaUploadComplete(notifyInfo: FileTransNotifyInfo) { + //LogCenter.log("onRichMediaUploadComplete($notifyInfo)", Level.DEBUG) + RichMediaUploadHandler.notify(notifyInfo) + } + override fun onRecvOnlineFileMsg(arrayList: ArrayList?) { LogCenter.log(("onRecvOnlineFileMsg" + arrayList?.joinToString { ", " }), Level.DEBUG) } @@ -359,10 +365,6 @@ internal object AioListener: IKernelMsgListener { } - override fun onRichMediaUploadComplete(fileTransNotifyInfo: FileTransNotifyInfo) { - - } - override fun onSearchGroupFileInfoUpdate(searchGroupFileResult: SearchGroupFileResult?) { LogCenter.log("onSearchGroupFileInfoUpdate($searchGroupFileResult)", Level.DEBUG) } 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 1fb0f49..8782728 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 @@ -336,7 +336,6 @@ internal object PrimitiveListener { val targetUid = pb[1, 3, 2, 3].asUtf8String val type = pb[1, 3, 2, 4].asInt val operation = ContactHelper.getUinByUidAsync(pb[1, 3, 2, 5].asUtf8String).toLong() - // 131 passive | 130 active | 3 kick_self val target = ContactHelper.getUinByUidAsync(targetUid).toLong() val subtype = when(type) { @@ -344,7 +343,6 @@ internal object PrimitiveListener { 131 -> NoticeSubType.Kick 3 -> NoticeSubType.KickMe else -> { - NoticeSubType.Kick } }