diff --git a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt index 7fd3dfd54..29fa62159 100644 --- a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt @@ -32,7 +32,6 @@ import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.createToGro import net.mamoe.mirai.internal.network.protocol.packet.chat.voice.PttStore import net.mamoe.mirai.internal.network.protocol.packet.list.ProfileService import net.mamoe.mirai.internal.utils.GroupPkgMsgParsingCache -import net.mamoe.mirai.internal.utils.estimateLength import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.data.* import net.mamoe.mirai.utils.* @@ -154,17 +153,15 @@ internal class GroupImpl( throw EventCancelledException("exception thrown when broadcasting GroupMessagePreSendEvent", it) }.message.asMessageChain() - val length = chain.estimateLength(this, 703) // 阈值为700左右,限制到3的倍数 - var imageCnt = 0 // 通过下方逻辑短路延迟计算 + var length: Int = 0 + var imageCnt: Int = 0 + chain.verityLength(message, this, lengthCallback = { + length = it + }, imageCntCallback = { + imageCnt = it + }) - if (length > 5000 || chain.count { it is Image }.apply { imageCnt = this } > 50) { - throw MessageTooLargeException( - this, message, chain, - "message(${chain.joinToString("", limit = 10)}) is too large. Allow up to 50 images or 5000 chars" - ) - } - - if (length > 702 || imageCnt > 2) { + if (length > 702 || imageCnt > 2) { // 阈值为700左右,限制到3的倍数 return MiraiImpl.lowLevelSendGroupLongOrForwardMessage( bot, this.id, diff --git a/mirai-core/src/commonMain/kotlin/contact/util.kt b/mirai-core/src/commonMain/kotlin/contact/util.kt index d643cb22e..7e37b6f6e 100644 --- a/mirai-core/src/commonMain/kotlin/contact/util.kt +++ b/mirai-core/src/commonMain/kotlin/contact/util.kt @@ -20,6 +20,7 @@ import net.mamoe.mirai.internal.message.MessageSourceToFriendImpl import net.mamoe.mirai.internal.message.ensureSequenceIdAvailable import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbSendMsg import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.createToFriend +import net.mamoe.mirai.internal.utils.estimateLength import net.mamoe.mirai.message.* import net.mamoe.mirai.message.data.* import net.mamoe.mirai.utils.cast @@ -49,6 +50,7 @@ internal suspend fun Friend.sendMessageImpl( }.getOrElse { throw EventCancelledException("exception thrown when broadcasting FriendMessagePreSendEvent", it) }.message.asMessageChain() + chain.verityLength(message, this, {}, {}) chain.firstIsInstanceOrNull()?.source?.ensureSequenceIdAvailable() @@ -89,6 +91,29 @@ internal fun Contact.logMessageSent(message: Message) { } } +internal inline fun MessageChain.verityLength( + message: Message, target: Contact, + lengthCallback: (Int) -> Unit, + imageCntCallback: (Int) -> Unit +) { + contract { + callsInPlace(lengthCallback, InvocationKind.EXACTLY_ONCE) + callsInPlace(imageCntCallback, InvocationKind.EXACTLY_ONCE) + } + + val chain = this + val length = estimateLength(target, 5001) + lengthCallback(length) + if (length > 5000 || count { it is Image }.apply { imageCntCallback(this) } > 50) { + throw MessageTooLargeException( + target, message, this, + "message(${ + chain.joinToString("", limit = 10) + }) is too large. Allow up to 50 images or 5000 chars" + ) + } +} + @Suppress("RemoveRedundantQualifierName") // compiler bug internal fun net.mamoe.mirai.event.events.MessageEvent.logMessageReceived() { fun renderGroupMessage(group: Group, senderName: String, sender: Member, message: MessageChain): String {