Fix long message, unify logs

This commit is contained in:
Him188 2020-04-23 21:56:29 +08:00
parent d584b765ab
commit 70f421aee8
3 changed files with 34 additions and 46 deletions

View File

@ -20,7 +20,6 @@ import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.io.ByteReadChannel import kotlinx.coroutines.io.ByteReadChannel
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.UnstableDefault import kotlinx.serialization.UnstableDefault
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration 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.data.proto.LongMsg
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.* import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.*
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList 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.io.serialization.toByteArray
import net.mamoe.mirai.qqandroid.utils.toReadPacket
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import kotlin.collections.asSequence import kotlin.collections.asSequence
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
@ -606,39 +607,16 @@ internal abstract class QQAndroidBotBase constructor(
) )
).toByteArray(LongMsg.ReqBody.serializer()) ).toByteArray(LongMsg.ReqBody.serializer())
var exception: Throwable? = null HighwayHelper.uploadImageToServers(
bot,
val success = response.proto.uint32UpIp.zip(response.proto.uint32UpPort).any { (ip, port) -> response.proto.uint32UpIp.zip(response.proto.uint32UpPort),
kotlin.runCatching { response.proto.msgSig,
withTimeoutOrNull((body.size * 1000L / 1024 / 10).coerceAtLeast(5000L)) { MiraiPlatformUtils.md5(body),
network.logger.verbose { "[Highway] Uploading group long message#$sequenceId to ${ip.toIpV4AddressString()}:$port: size=${body.size}" } body.toReadPacket(),
HighwayHelper.uploadImage( body.size.toLongUnsigned(),
client, "group long message",
serverIp = ip.toIpV4AddressString(), 27
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)
}
} }
} }

View File

@ -416,7 +416,7 @@ internal class GroupImpl(
response.uploadIpList.zip(response.uploadPortList), response.uploadIpList.zip(response.uploadPortList),
response.uKey, response.uKey,
image, image,
kind = "group", kind = "group image",
commandId = 2 commandId = 2
) )
val resourceId = image.calculateImageResourceId() val resourceId = image.calculateImageResourceId()

View File

@ -102,8 +102,6 @@ internal suspend fun HttpClient.postImage(
@OptIn(MiraiInternalAPI::class, InternalSerializationApi::class) @OptIn(MiraiInternalAPI::class, InternalSerializationApi::class)
internal object HighwayHelper { internal object HighwayHelper {
@OptIn(ExperimentalTime::class)
suspend fun uploadImageToServers( suspend fun uploadImageToServers(
bot: QQAndroidBot, bot: QQAndroidBot,
servers: List<Pair<Int, Int>>, servers: List<Pair<Int, Int>>,
@ -111,14 +109,26 @@ internal object HighwayHelper {
image: ExternalImage, image: ExternalImage,
kind: String, kind: String,
commandId: Int commandId: Int
) = uploadImageToServers(bot, servers, uKey, image.md5, image.input, image.inputSize, kind, commandId)
@OptIn(ExperimentalTime::class)
suspend fun uploadImageToServers(
bot: QQAndroidBot,
servers: List<Pair<Int, Int>>,
uKey: ByteArray,
md5: ByteArray,
input: Any,
inputSize: Long,
kind: String,
commandId: Int
) = servers.retryWithServers( ) = servers.retryWithServers(
(image.inputSize * 1000 / 1024 / 10).coerceAtLeast(5000), (inputSize * 1000 / 1024 / 10).coerceAtLeast(5000),
onFail = { onFail = {
throw IllegalStateException("cannot upload $kind image, failed on all servers.", it) throw IllegalStateException("cannot upload $kind, failed on all servers.", it)
} }
) { ip, port -> ) { ip, port ->
bot.network.logger.verbose { 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 { val time = measureTime {
@ -126,21 +136,21 @@ internal object HighwayHelper {
client = bot.client, client = bot.client,
serverIp = ip, serverIp = ip,
serverPort = port, serverPort = port,
imageInput = image.input, imageInput = input,
inputSize = image.inputSize.toInt(), inputSize = inputSize.toInt(),
fileMd5 = image.md5, fileMd5 = md5,
ticket = uKey, ticket = uKey,
commandId = commandId commandId = commandId
) )
} }
bot.network.logger.verbose { 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) @OptIn(InternalCoroutinesApi::class)
private suspend fun uploadImage( internal suspend fun uploadImage(
client: QQAndroidClient, client: QQAndroidClient,
serverIp: String, serverIp: String,
serverPort: Int, serverPort: Int,