Просмотр исходного кода

Send temp messages as friend messages if a target Member is also a friend

Him188 5 лет назад
Родитель
Сommit
8e8f91bbee

+ 34 - 24
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<Friend> {
-        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 {

+ 9 - 79
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)"
-}
+}

+ 2 - 3
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<Member> {
-        return sendMessageImpl(message).also {
-            logMessageSent(message)
-        }
+        return (this.asFriendOrNull()?.sendMessageImpl(this, message) ?: sendMessageImpl(message))
+            .also { logMessageSent(message) }
     }
 
     private suspend fun sendMessageImpl(message: Message): MessageReceipt<Member> {

+ 2 - 2
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<Friend> {
+internal suspend fun <T : Contact> Friend.sendMessageImpl(generic: T, message: Message): MessageReceipt<T> {
     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<Fr
             }.sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS
         ) { "send message failed" }
     }
-    return MessageReceipt(source, this, null)
+    return MessageReceipt(source, generic, null)
 }
 
 @OptIn(MiraiInternalAPI::class, MiraiExperimentalAPI::class)