Fix longMessage size detect

This commit is contained in:
Him188 2020-03-30 15:48:42 +08:00
parent d432c5f1d0
commit e3a8ae8d90
2 changed files with 38 additions and 7 deletions

View File

@ -30,6 +30,8 @@ import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
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.utils.chineseLength
import net.mamoe.mirai.qqandroid.utils.sumUpTo
import net.mamoe.mirai.qqandroid.utils.toIpV4AddressString
import net.mamoe.mirai.utils.*
import kotlin.contracts.ExperimentalContracts
@ -271,7 +273,7 @@ internal class GroupImpl(
return members.delegate.filteringGetOrNull { it.id == id }
}
@OptIn(MiraiExperimentalAPI::class)
@OptIn(MiraiExperimentalAPI::class, LowLevelAPI::class)
@JvmSynthetic
override suspend fun sendMessage(message: Message): MessageReceipt<Group> {
check(!isBotMuted) { "bot is muted. Remaining seconds=$botMuteRemaining" }
@ -281,11 +283,14 @@ internal class GroupImpl(
}
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))
) {
if (event.message.sumUpTo(800) { it, upTo ->
when (it) {
is QuoteReply -> 700
is Image -> 300
is PlainText -> it.stringValue.chineseLength(upTo)
else -> it.toString().length
}
} >= 800) {
return bot._lowLevelSendLongGroupMessage(this.id, message)
}
}

View File

@ -28,4 +28,30 @@ internal fun Int.toIpV4AddressString(): String {
}
}
}
}
}
internal fun String.chineseLength(upTo: Int): Int {
return this.sumUpTo(upTo) { if (it in '\u0391'..'\uFFE5') 3 else 1 }
}
internal inline fun <T> Iterable<T>.sumUpTo(upTo: Int, selector: (T, remaining: Int) -> Int): Int {
var sum = 0
for (element in this) {
if (sum >= upTo) {
return sum
}
sum += selector(element, (upTo - sum).coerceAtLeast(0))
}
return sum
}
internal inline fun CharSequence.sumUpTo(upTo: Int, selector: (Char) -> Int): Int {
var sum: Int = 0
for (element in this) {
sum += selector(element)
if (sum >= upTo) {
return sum
}
}
return sum
}