瀏覽代碼

Support long message in general `sendMessage`

Him188 6 年之前
父節點
當前提交
a6079f3eaf

+ 7 - 10
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt

@@ -31,6 +31,7 @@ import net.mamoe.mirai.contact.*
 import net.mamoe.mirai.data.*
 import net.mamoe.mirai.event.broadcast
 import net.mamoe.mirai.event.events.MessageRecallEvent
+import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.message.data.*
 import net.mamoe.mirai.qqandroid.contact.MemberInfoImpl
 import net.mamoe.mirai.qqandroid.contact.QQImpl
@@ -370,13 +371,11 @@ internal abstract class QQAndroidBotBase constructor(
 
     @LowLevelAPI
     @MiraiExperimentalAPI
-    override suspend fun _lowLevelSendLongMessage(groupCode: Long, message: Message) {
+    override suspend fun _lowLevelSendLongGroupMessage(groupCode: Long, message: Message): MessageReceipt<Group> {
         val chain = message.asMessageChain()
         check(chain.toString().length <= 4500 && chain.count { it is Image } <= 50) { "message is too large. Allow up to 4500 chars or 50 images" }
         val group = getGroup(groupCode)
 
-        // TODO: 2020/3/26 util 方法来添加单例元素
-
         val time = currentTimeSeconds
 
         network.run {
@@ -432,14 +431,12 @@ internal abstract class QQAndroidBotBase constructor(
                 }
             }
 
-            group.sendMessage(
+            return group.sendMessage(
                 RichMessage.longMessage(
-                    brief = chain.joinToString(limit = 30) {
-                        when (it) {
-                            is PlainText -> it.stringValue
-                            is At -> it.toString()
-                            else -> ""
-                        }
+                    brief = chain.toString().let { // already cached
+                        if (it.length > 27) {
+                            it.take(27) + "..."
+                        } else it
                     },
                     resId = resId,
                     timeSeconds = time

+ 13 - 3
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt

@@ -23,9 +23,7 @@ import net.mamoe.mirai.event.broadcast
 import net.mamoe.mirai.event.events.*
 import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
 import net.mamoe.mirai.message.MessageReceipt
-import net.mamoe.mirai.message.data.Message
-import net.mamoe.mirai.message.data.OfflineGroupImage
-import net.mamoe.mirai.message.data.asMessageChain
+import net.mamoe.mirai.message.data.*
 import net.mamoe.mirai.qqandroid.QQAndroidBot
 import net.mamoe.mirai.qqandroid.message.MessageSourceFromSendGroup
 import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
@@ -273,6 +271,7 @@ internal class GroupImpl(
         return members.delegate.filteringGetOrNull { it.id == id }
     }
 
+    @OptIn(MiraiExperimentalAPI::class)
     @JvmSynthetic
     override suspend fun sendMessage(message: Message): MessageReceipt<Group> {
         check(!isBotMuted) { "bot is muted. Remaining seconds=$botMuteRemaining" }
@@ -280,6 +279,17 @@ internal class GroupImpl(
         if (event.isCancelled) {
             throw EventCancelledException("cancelled by GroupMessageSendEvent")
         }
+
+        if (message !is LongMessage) {
+            val length = event.message.toString().length
+            if (length > 4000
+                || event.message.count { it is Image } > 3
+                || (event.message.any<QuoteReply>() && (event.message.any<Image>() || length > 100))
+            ) {
+                return bot._lowLevelSendLongGroupMessage(this.id, message)
+            }
+        }
+
         lateinit var source: MessageSourceFromSendGroup
         bot.network.run {
             val response: MessageSvc.PbSendMsg.Response = MessageSvc.PbSendMsg.ToGroup(

+ 4 - 9
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/messages.kt

@@ -315,15 +315,10 @@ private fun MessageChain.cleanupRubbishMessageElements(): MessageChain {
     var last: SingleMessage? = null
     return buildMessageChain(initialSize = this.count()) {
         [email protected] { element ->
-            if (last == null) {
-                last = element
-                return@forEach
-            } else {
-                if (last is LongMessage && element is PlainText) {
-                    if (element == UNSUPPORTED_MERGED_MESSAGE_PLAIN) {
-                        last = element
-                        return@forEach
-                    }
+            if (last is LongMessage && element is PlainText) {
+                if (element == UNSUPPORTED_MERGED_MESSAGE_PLAIN) {
+                    last = element
+                    return@forEach
                 }
             }
 

+ 2 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt

@@ -13,6 +13,7 @@ import kotlinx.coroutines.Job
 import net.mamoe.mirai.contact.Group
 import net.mamoe.mirai.contact.QQ
 import net.mamoe.mirai.data.*
+import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.message.data.Message
 import net.mamoe.mirai.message.data.MessageSource
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
@@ -148,7 +149,7 @@ interface LowLevelBotAPIAccessor {
     @SinceMirai("0.31.0")
     @LowLevelAPI
     @MiraiExperimentalAPI
-    suspend fun _lowLevelSendLongMessage(groupCode: Long, message: Message)
+    suspend fun _lowLevelSendLongGroupMessage(groupCode: Long, message: Message): MessageReceipt<Group>
 }
 
 /**

+ 2 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessagePacket.kt

@@ -7,7 +7,7 @@
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE")
+@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE", "unused")
 
 package net.mamoe.mirai.message
 
@@ -153,6 +153,7 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact> : Packet, Bot
     /**
      * 引用这个消息
      */
+    @ExperimentalMessageSource
     inline fun MessageChain.quote(): QuoteReplyToSend = this.quote(sender)
 
     operator fun <M : Message> get(at: Message.Key<M>): M {

+ 2 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt

@@ -54,7 +54,8 @@ sealed class QuoteReplyToSend
  * 引用这条消息.
  * @see sender 消息发送人.
  */
-@OptIn(MiraiInternalAPI::class, ExperimentalMessageSource::class)
+@ExperimentalMessageSource
+@OptIn(MiraiInternalAPI::class)
 fun MessageChain.quote(sender: QQ?): QuoteReplyToSend {
     this.firstOrNull<MessageSource>()?.let {
         return it.quote(sender)