diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt index 0a031d867..25a2f92d3 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt @@ -20,7 +20,6 @@ import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.async import kotlinx.coroutines.io.ByteReadChannel import kotlinx.coroutines.withContext -import kotlinx.coroutines.withTimeoutOrNull import kotlinx.serialization.UnstableDefault import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonConfiguration @@ -50,8 +49,10 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.qqandroid.network.protocol.data.proto.LongMsg import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.* import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList -import net.mamoe.mirai.qqandroid.utils.* +import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils +import net.mamoe.mirai.qqandroid.utils.encodeToString import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray +import net.mamoe.mirai.qqandroid.utils.toReadPacket import net.mamoe.mirai.utils.* import kotlin.collections.asSequence import kotlin.contracts.ExperimentalContracts @@ -606,39 +607,16 @@ internal abstract class QQAndroidBotBase constructor( ) ).toByteArray(LongMsg.ReqBody.serializer()) - var exception: Throwable? = null - - val success = response.proto.uint32UpIp.zip(response.proto.uint32UpPort).any { (ip, port) -> - kotlin.runCatching { - withTimeoutOrNull((body.size * 1000L / 1024 / 10).coerceAtLeast(5000L)) { - network.logger.verbose { "[Highway] Uploading group long message#$sequenceId to ${ip.toIpV4AddressString()}:$port: size=${body.size}" } - HighwayHelper.uploadImage( - client, - serverIp = ip.toIpV4AddressString(), - serverPort = port, - ticket = response.proto.msgSig, // 104 - imageInput = body.toReadPacket(), - inputSize = body.size, - fileMd5 = MiraiPlatformUtils.md5(body), - commandId = 27 // long msg - ) - network.logger.verbose { "[Highway] Uploading group long message#$sequenceId: succeed" } - true - } ?: kotlin.run { - network.logger.verbose { "[Highway] Uploading group long message: timeout, retrying next server" } - false - } - }.getOrElse { - exception?.addSuppressedMirai(it) - exception = it - false - } - } - - if (!success) { - throw IllegalStateException("cannot upload group long message, failed on all servers.", - exception) - } + HighwayHelper.uploadImageToServers( + bot, + response.proto.uint32UpIp.zip(response.proto.uint32UpPort), + response.proto.msgSig, + MiraiPlatformUtils.md5(body), + body.toReadPacket(), + body.size.toLongUnsigned(), + "group long message", + 27 + ) } } diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt index e44f587d8..55a63170b 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt @@ -416,7 +416,7 @@ internal class GroupImpl( response.uploadIpList.zip(response.uploadPortList), response.uKey, image, - kind = "group", + kind = "group image", commandId = 2 ) val resourceId = image.calculateImageResourceId() diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt index 4314b4c6c..d7161dafd 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt @@ -102,8 +102,6 @@ internal suspend fun HttpClient.postImage( @OptIn(MiraiInternalAPI::class, InternalSerializationApi::class) internal object HighwayHelper { - - @OptIn(ExperimentalTime::class) suspend fun uploadImageToServers( bot: QQAndroidBot, servers: List>, @@ -111,14 +109,26 @@ internal object HighwayHelper { image: ExternalImage, kind: String, commandId: Int + ) = uploadImageToServers(bot, servers, uKey, image.md5, image.input, image.inputSize, kind, commandId) + + @OptIn(ExperimentalTime::class) + suspend fun uploadImageToServers( + bot: QQAndroidBot, + servers: List>, + uKey: ByteArray, + md5: ByteArray, + input: Any, + inputSize: Long, + kind: String, + commandId: Int ) = servers.retryWithServers( - (image.inputSize * 1000 / 1024 / 10).coerceAtLeast(5000), + (inputSize * 1000 / 1024 / 10).coerceAtLeast(5000), onFail = { - throw IllegalStateException("cannot upload $kind image, failed on all servers.", it) + throw IllegalStateException("cannot upload $kind, failed on all servers.", it) } ) { ip, port -> bot.network.logger.verbose { - "[Highway] Uploading $kind image to ${ip}:$port, size=${image.inputSize / 1024} KiB" + "[Highway] Uploading $kind to ${ip}:$port, size=${inputSize / 1024} KiB" } val time = measureTime { @@ -126,21 +136,21 @@ internal object HighwayHelper { client = bot.client, serverIp = ip, serverPort = port, - imageInput = image.input, - inputSize = image.inputSize.toInt(), - fileMd5 = image.md5, + imageInput = input, + inputSize = inputSize.toInt(), + fileMd5 = md5, ticket = uKey, commandId = commandId ) } bot.network.logger.verbose { - "[Highway] Uploading $kind image: succeed at ${(image.inputSize.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s" + "[Highway] Uploading $kind: succeed at ${(inputSize.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s" } } @OptIn(InternalCoroutinesApi::class) - private suspend fun uploadImage( + internal suspend fun uploadImage( client: QQAndroidClient, serverIp: String, serverPort: Int,