From 0d58e6e3abdddfb41e9bcdf8a4b087ca67bb07a3 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Thu, 11 Feb 2021 08:48:01 +0800 Subject: [PATCH] Convert `CRLF(\r\n)`, `CR(\r)` to `LF(\n)`; fix #1010 --- .../api/binary-compatibility-validator.api | 2 ++ .../kotlin/utils/BotConfiguration.kt | 12 +++++++++ .../kotlin/message/ReceiveMessageHandler.kt | 25 ++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/binary-compatibility-validator/api/binary-compatibility-validator.api b/binary-compatibility-validator/api/binary-compatibility-validator.api index a3782c3d4..2bbdc0fe8 100644 --- a/binary-compatibility-validator/api/binary-compatibility-validator.api +++ b/binary-compatibility-validator/api/binary-compatibility-validator.api @@ -5382,6 +5382,7 @@ public class net/mamoe/mirai/utils/BotConfiguration { public final fun getReconnectionRetryTimes ()I public final fun getWorkingDir ()Ljava/io/File; public final synthetic fun inheritCoroutineContext (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun isConvertLineSeparator ()Z public final fun loadDeviceInfoJson (Ljava/lang/String;)V public final fun noBotLog ()V public final fun noNetworkLog ()V @@ -5408,6 +5409,7 @@ public class net/mamoe/mirai/utils/BotConfiguration { public final fun setBotLoggerSupplier (Lkotlin/jvm/functions/Function1;)V public final fun setCacheDir (Ljava/io/File;)V public final fun setContactListCache (Lnet/mamoe/mirai/utils/BotConfiguration$ContactListCache;)V + public final fun setConvertLineSeparator (Z)V public final fun setDeviceInfo (Lkotlin/jvm/functions/Function1;)V public final fun setFirstReconnectDelayMillis (J)V public final fun setHeartbeatPeriodMillis (J)V diff --git a/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt b/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt index 197a19153..34cbf3085 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt @@ -467,9 +467,21 @@ public open class BotConfiguration { // open for Java new.networkLoggerSupplier = networkLoggerSupplier new.cacheDir = cacheDir new.contactListCache = contactListCache + new.convertLineSeparator = convertLineSeparator } } + /** + * 是否处理接受到的特殊换行符, 默认为 `true` + * + * - 若为 `true`, 会将收到的 `CRLF(\r\n)` 和 `CR(\r)` 替换为 `LF(\n)` + * - 若为 `false`, 则不做处理 + * + * @since 2.4 + */ + @get:JvmName("isConvertLineSeparator") + public var convertLineSeparator: Boolean = true + /** 标注一个配置 DSL 函数 */ @Target(AnnotationTarget.FUNCTION) @DslMarker diff --git a/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt b/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt index 14eb70e0c..2a22cb2a2 100644 --- a/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt +++ b/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt @@ -13,6 +13,7 @@ import kotlinx.io.core.discardExact import kotlinx.io.core.readUInt import net.mamoe.mirai.Bot import net.mamoe.mirai.contact.Contact +import net.mamoe.mirai.internal.asQQAndroidBot import net.mamoe.mirai.internal.message.ReceiveMessageTransformer.cleanupRubbishMessageElements import net.mamoe.mirai.internal.message.ReceiveMessageTransformer.joinToMessageChain import net.mamoe.mirai.internal.message.ReceiveMessageTransformer.toVoice @@ -427,14 +428,36 @@ private object ReceiveMessageTransformer { /** * 解析 [ForwardMessageInternal], [LongMessageInternal] + * 并处理换行符问题 */ internal suspend fun MessageChain.refine(contact: Contact): MessageChain { - if (none { it is RefinableMessage }) return this + val convertLineSeparator = contact.bot.asQQAndroidBot().configuration.convertLineSeparator + + if (none { + it is RefinableMessage + || (it is PlainText && convertLineSeparator && it.content.contains('\r')) + } + ) return this + + val builder = MessageChainBuilder(this.size) for (singleMessage in this) { if (singleMessage is RefinableMessage) { val v = singleMessage.refine(contact, this) if (v != null) builder.add(v) + } else if (singleMessage is PlainText && convertLineSeparator) { + val content = singleMessage.content + if (content.contains('\r')) { + builder.add( + PlainText( + content + .replace("\r\n", "\n") + .replace('\r', '\n') + ) + ) + } else { + builder.add(singleMessage) + } } else { builder.add(singleMessage) }