Shamrock: fix #109

This commit is contained in:
ikechan8370 2023-11-30 22:38:44 +08:00
parent 7d8772ebf6
commit 2fdcfe332b
3 changed files with 78 additions and 21 deletions

View File

@ -16,10 +16,8 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.time.withTimeoutOrNull
import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.json.JsonArray
import moe.fuqiuluo.proto.protobufOf
import moe.fuqiuluo.shamrock.helper.ContactHelper
import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter
@ -174,8 +172,9 @@ internal object MsgSvc: BaseSvc() {
chatType: Int,
peedId: String,
message: JsonArray,
fromId: String = peedId
): Pair<Long, Int> {
fromId: String = peedId,
retryCnt: Int = 3
): Result<Pair<Long, Int>> {
//LogCenter.log(message.toString(), Level.ERROR)
//callback.msgHash = result.second 什么垃圾代码万一cb比你快你不就寄了
@ -184,12 +183,25 @@ internal object MsgSvc: BaseSvc() {
MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> {
prepareTempChatFromGroup(fromId, peedId).onFailure {
LogCenter.log("主动临时消息,创建临时会话失败。", Level.ERROR)
return -1L to 0
return Result.failure(Exception("主动临时消息,创建临时会话失败。"))
}
}
}
return MessageHelper.sendMessageWithoutMsgId(chatType, peedId, message, MessageCallback(peedId, 0), fromId)
val result = MessageHelper.sendMessageWithoutMsgId(
chatType,
peedId,
message,
fromId,
MessageCallback(peedId, 0)
)
return if (result.isFailure && retryCnt > 0) {
// 可能网络问题出现红色感叹号,重试
// 例如 rich media transfer failed
delay(100)
sendToAio(chatType, peedId, message, fromId, retryCnt - 1)
} else {
result
}
}
suspend fun getMultiMsg(resId: String): Result<List<MsgRecord>> {

View File

@ -6,6 +6,10 @@ import com.tencent.qqnt.kernel.nativeinterface.IOperateCallback
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
import com.tencent.qqnt.msg.api.IMsgService
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
@ -20,6 +24,8 @@ import moe.fuqiuluo.shamrock.tools.asJsonObjectOrNull
import moe.fuqiuluo.shamrock.tools.asString
import moe.fuqiuluo.shamrock.tools.json
import moe.fuqiuluo.shamrock.tools.jsonArray
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlin.math.abs
internal object MessageHelper {
@ -36,31 +42,62 @@ internal object MessageHelper {
}.second.filter {
it.elementType != -1
} as ArrayList<MsgElement>
return sendMessageWithoutMsgId(chatType, peerId, msg, callback, fromId)
return sendMessageWithoutMsgId(chatType, peerId, msg, fromId, callback)
}
@OptIn(DelicateCoroutinesApi::class)
suspend fun sendMessageWithoutMsgId(
chatType: Int,
peerId: String,
message: JsonArray,
callback: IOperateCallback,
fromId: String = peerId
): Pair<Long, Int> {
fromId: String = peerId,
callback: IOperateCallback
): Result<Pair<Long, Int>> {
val uniseq = generateMsgId(chatType)
val msg = messageArrayToMessageElements(chatType, uniseq.second, peerId, message).also {
if (it.second.isEmpty() && !it.first) error("消息合成失败,请查看日志或者检查输入。")
}.second.filter {
it.elementType != -1
} as ArrayList<MsgElement>
return sendMessageWithoutMsgId(chatType, peerId, msg, callback, fromId)
val totalSize = msg.filter {
it.elementType == MsgConstant.KELEMTYPEPIC ||
it.elementType == MsgConstant.KELEMTYPEPTT ||
it.elementType == MsgConstant.KELEMTYPEVIDEO
}.map {
(it.picElement?.fileSize ?: 0) + (it.pttElement?.fileSize
?: 0) + (it.videoElement?.fileSize ?: 0)
}.reduceOrNull { a, b -> a + b } ?: 0
val estimateTime = (totalSize / (300 * 1024)) * 1000 + 5000
lateinit var sendResultPair: Pair<Long, Int>
val sendRet = withTimeoutOrNull<Pair<Int, String>>(estimateTime) {
suspendCoroutine {
GlobalScope.launch {
sendResultPair = sendMessageWithoutMsgId(
chatType,
peerId,
msg,
fromId
) { code, message ->
callback.onResult(code, message)
it.resume(code to message)
}
}
}
}
if (sendRet?.first != 0) {
return Result.failure(Exception(sendRet?.second ?: "发送消息超时"))
}
return Result.success(sendResultPair)
// return sendMessageWithoutMsgId(chatType, peerId, msg, fromId, callback)
}
suspend fun sendMessageWithoutMsgId(
chatType: Int,
peerId: String,
message: ArrayList<MsgElement>,
callback: IOperateCallback,
fromId: String = peerId
fromId: String = peerId,
callback: IOperateCallback
): Pair<Long, Int> {
return sendMessageWithoutMsgId(generateContact(chatType, peerId, fromId), message, callback)
}

View File

@ -92,12 +92,16 @@ internal object SendMessage: IActionHandler() {
MsgSvc.sendToAio(chatType, peerId, msg, fromId = fromId)
}
}
if (result.first <= 0) {
if (result.isFailure) {
return logic(result.exceptionOrNull()?.message ?: "", echo)
}
val pair = result.getOrNull() ?: Pair(0L, 0)
if (pair.first <= 0) {
return logic("send message failed", echo = echo)
}
return ok(MessageResult(
msgId = result.second,
time = (result.first * 0.001).toLong()
msgId = pair.second,
time = (pair.first * 0.001).toLong()
), echo = echo)
}
@ -109,12 +113,16 @@ internal object SendMessage: IActionHandler() {
// return logic("contact is not found", echo = echo)
//}
val result = MsgSvc.sendToAio(chatType, peerId, message, fromId = fromId)
if (result.first <= 0) {
if (result.isFailure) {
return logic(result.exceptionOrNull()?.message ?: "", echo)
}
val pair = result.getOrNull() ?: Pair(0L, 0)
if (pair.first <= 0) {
return logic("send message failed", echo = echo)
}
return ok(MessageResult(
msgId = result.second,
time = (result.first * 0.001).toLong()
msgId = pair.second,
time = (pair.first * 0.001).toLong()
), echo)
}