diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/FriendImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/FriendImpl.kt index 9c00a644d..62381ea6e 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/FriendImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/FriendImpl.kt @@ -31,14 +31,14 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352 import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils import net.mamoe.mirai.qqandroid.utils.toUHexString -import net.mamoe.mirai.utils.ExternalImage -import net.mamoe.mirai.utils.MiraiInternalAPI -import net.mamoe.mirai.utils.getValue -import net.mamoe.mirai.utils.unsafeWeakRef +import net.mamoe.mirai.utils.* import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract import kotlin.coroutines.CoroutineContext import kotlin.jvm.JvmSynthetic +import kotlin.math.roundToInt +import kotlin.time.ExperimentalTime +import kotlin.time.measureTime internal inline class FriendInfoImpl( private val jceFriendInfo: net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo @@ -72,13 +72,13 @@ internal class FriendImpl( @JvmSynthetic @Suppress("DuplicatedCode") override suspend fun sendMessage(message: Message): MessageReceipt { - return sendMessageImpl(message).also { + return sendMessageImpl(this, message).also { logMessageSent(message) } } @JvmSynthetic - @OptIn(MiraiInternalAPI::class) + @OptIn(MiraiInternalAPI::class, ExperimentalStdlibApi::class, ExperimentalTime::class) override suspend fun uploadImage(image: ExternalImage): OfflineFriendImage = try { if (BeforeImageUploadEvent(this, image).broadcast().isCancelled) { throw EventCancelledException("cancelled by BeforeImageUploadEvent.ToGroup") @@ -102,24 +102,34 @@ internal class FriendImpl( ImageUploadEvent.Succeed(this@FriendImpl, image, it).broadcast() } is LongConn.OffPicUp.Response.RequireUpload -> { - MiraiPlatformUtils.Http.postImage( - "0x6ff0070", - bot.id, - null, - imageInput = image.input, - inputSize = image.inputSize, - uKeyHex = response.uKey.toUHexString("") - ) - //HighwayHelper.uploadImage( - // client = bot.client, - // serverIp = response.serverIp[0].toIpV4AddressString(), - // serverPort = response.serverPort[0], - // imageInput = image.input, - // inputSize = image.inputSize.toInt(), - // fileMd5 = image.md5, - // uKey = response.uKey, - // commandId = 1 - //) + bot.network.logger.verbose { + "[Http] Uploading friend image, size=${image.inputSize / 1024} KiB" + } + + val time = measureTime { + MiraiPlatformUtils.Http.postImage( + "0x6ff0070", + bot.id, + null, + imageInput = image.input, + inputSize = image.inputSize, + uKeyHex = response.uKey.toUHexString("") + ) + } + + bot.network.logger.verbose { + "[Http] Uploading friend image: succeed at ${(image.inputSize.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s" + } + + /* + HighwayHelper.uploadImageToServers( + bot, + response.serverIp.zip(response.serverPort), + response.uKey, + image, + kind = "friend", + commandId = 1 + )*/ // 为什么不能 ?? return OfflineFriendImage(response.resourceId).also { 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 9194a771a..e44f587d8 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 @@ -13,7 +13,6 @@ package net.mamoe.mirai.qqandroid.contact import kotlinx.coroutines.launch -import kotlinx.coroutines.withTimeoutOrNull import kotlinx.io.core.Closeable import net.mamoe.mirai.LowLevelAPI import net.mamoe.mirai.contact.* @@ -33,17 +32,13 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc import net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService -import net.mamoe.mirai.qqandroid.utils.addSuppressedMirai import net.mamoe.mirai.qqandroid.utils.estimateLength -import net.mamoe.mirai.qqandroid.utils.toIpV4AddressString import net.mamoe.mirai.utils.* import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract import kotlin.coroutines.CoroutineContext import kotlin.jvm.JvmSynthetic -import kotlin.math.roundToInt import kotlin.time.ExperimentalTime -import kotlin.time.measureTime @OptIn(ExperimentalContracts::class) internal fun GroupImpl.Companion.checkIsInstance(instance: Group) { @@ -412,86 +407,21 @@ internal class GroupImpl( } is ImgStore.GroupPicUp.Response.FileExists -> { val resourceId = image.calculateImageResourceId() -// return NotOnlineImageFromFile( -// resourceId = resourceId, -// md5 = response.fileInfo.fileMd5, -// filepath = resourceId, -// fileLength = response.fileInfo.fileSize.toInt(), -// height = response.fileInfo.fileHeight, -// width = response.fileInfo.fileWidth, -// imageType = response.fileInfo.fileType, -// fileId = response.fileId.toInt() -// ) - // println("NMSL") return OfflineGroupImage(imageId = resourceId) .also { ImageUploadEvent.Succeed(this@GroupImpl, image, it).broadcast() } } is ImgStore.GroupPicUp.Response.RequireUpload -> { - // 每 10KB 等 1 秒, 最少等待 5 秒 - var exception: Throwable? = null - val success = response.uploadIpList.zip(response.uploadPortList).any { (ip, port) -> - kotlin.runCatching { - withTimeoutOrNull((image.inputSize * 1000 / 1024 / 10).coerceAtLeast(5000)) { - bot.network.logger.verbose { "[Highway] Uploading group image to ${ip.toIpV4AddressString()}:$port, size=${image.inputSize / 1024} KiB" } - - val time = measureTime { - HighwayHelper.uploadImage( - client = bot.client, - serverIp = ip.toIpV4AddressString(), - serverPort = port, - imageInput = image.input, - inputSize = image.inputSize.toInt(), - fileMd5 = image.md5, - ticket = response.uKey, - commandId = 2 - ) - } - bot.network.logger.verbose { "[Highway] Uploading group image: succeed at ${(image.inputSize.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s" } - true - } ?: kotlin.run { - bot.network.logger.verbose { "[Highway] Uploading group image: timeout, retrying next server" } - false - } - }.getOrElse { - exception?.addSuppressedMirai(it) - exception = it - false - } - } - - if (!success) { - throw IllegalStateException("cannot upload group image, failed on all servers.", exception) - } - + HighwayHelper.uploadImageToServers( + bot, + response.uploadIpList.zip(response.uploadPortList), + response.uKey, + image, + kind = "group", + commandId = 2 + ) val resourceId = image.calculateImageResourceId() - // return NotOnlineImageFromFile( - // resourceId = resourceId, - // md5 = image.md5, - // filepath = resourceId, - // fileLength = image.inputSize.toInt(), - // height = image.height, - // width = image.width, - // imageType = image.imageType, - // fileId = response.fileId.toInt() - // ) return OfflineGroupImage(imageId = resourceId) .also { ImageUploadEvent.Succeed(this@GroupImpl, image, it).broadcast() } - /* - fileId = response.fileId.toInt(), - fileType = 0, // ? - height = image.height, - width = image.width, - imageType = image.imageType, - bizType = 0, - serverIp = response.uploadIpList.first(), - serverPort = response.uploadPortList.first(), - signature = image.md5, - size = image.inputSize.toInt(), - useful = 1, - source = 200, - original = 1, - pbReserve = EMPTY_BYTE_ARRAY - */ } } } @@ -500,4 +430,4 @@ internal class GroupImpl( } override fun toString(): String = "Group($id)" -} \ No newline at end of file +} diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt index 9e95341f9..77a8c3d92 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt @@ -54,9 +54,8 @@ internal class MemberImpl constructor( @JvmSynthetic override suspend fun sendMessage(message: Message): MessageReceipt { - return sendMessageImpl(message).also { - logMessageSent(message) - } + return (this.asFriendOrNull()?.sendMessageImpl(this, message) ?: sendMessageImpl(message)) + .also { logMessageSent(message) } } private suspend fun sendMessageImpl(message: Message): MessageReceipt { diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt index cf68a81de..8e7c3a47f 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt @@ -31,7 +31,7 @@ import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.verbose @OptIn(MiraiInternalAPI::class) -internal suspend fun Friend.sendMessageImpl(message: Message): MessageReceipt { +internal suspend fun Friend.sendMessageImpl(generic: T, message: Message): MessageReceipt { val event = MessageSendEvent.FriendMessageSendEvent(this, message.asMessageChain()).broadcast() if (event.isCancelled) { throw EventCancelledException("cancelled by FriendMessageSendEvent") @@ -49,7 +49,7 @@ internal suspend fun Friend.sendMessageImpl(message: Message): MessageReceipt() is MessageSvc.PbSendMsg.Response.SUCCESS ) { "send message failed" } } - return MessageReceipt(source, this, null) + return MessageReceipt(source, generic, null) } @OptIn(MiraiInternalAPI::class, MiraiExperimentalAPI::class)