From bca98c72d54a8ed717d4463e69411fef73a98c7e Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 9 Jan 2021 13:11:07 +0800 Subject: [PATCH] Fix StackOverflowError in QuoteReply fix #829 --- .../message/MessageSerializersImpl.kt | 13 +++++---- .../kotlin/message/offlineSourceImpl.kt | 28 +++++++++++++++++-- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/mirai-core-api/src/commonMain/kotlin/internal/message/MessageSerializersImpl.kt b/mirai-core-api/src/commonMain/kotlin/internal/message/MessageSerializersImpl.kt index 84b801a3a..2d49f6a8d 100644 --- a/mirai-core-api/src/commonMain/kotlin/internal/message/MessageSerializersImpl.kt +++ b/mirai-core-api/src/commonMain/kotlin/internal/message/MessageSerializersImpl.kt @@ -1,10 +1,10 @@ /* - * Copyright 2020 Mamoe Technologies and contributors. + * Copyright 2019-2021 Mamoe Technologies and contributors. * - * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. - * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * - * https://github.com/mamoe/mirai/blob/master/LICENSE + * https://github.com/mamoe/mirai/blob/master/LICENSE */ package net.mamoe.mirai.internal.message @@ -46,7 +46,10 @@ public open class MessageSourceSerializerImpl(serialName: String) : resultantDescriptor = buildClassSerialDescriptor(serialName) { takeElementsFrom(SerialData.serializer().descriptor) }, - serialize = { SerialData(kind, botId, ids, internalIds, time, fromId, targetId, originalMessage) }, + serialize = { + // TODO: 2021-01-09 解决因为 originMessage 中 MessageSource 与 this 相同造成的死循环 + SerialData(kind, botId, ids, internalIds, time, fromId, targetId, originalMessage) + }, deserialize = { Mirai.constructMessageSource(botId, kind, fromId, targetId, ids, time, internalIds, originalMessage) } diff --git a/mirai-core/src/commonMain/kotlin/message/offlineSourceImpl.kt b/mirai-core/src/commonMain/kotlin/message/offlineSourceImpl.kt index 367e34b6a..4853615b0 100644 --- a/mirai-core/src/commonMain/kotlin/message/offlineSourceImpl.kt +++ b/mirai-core/src/commonMain/kotlin/message/offlineSourceImpl.kt @@ -25,19 +25,20 @@ import net.mamoe.mirai.utils.mapToIntArray import java.util.concurrent.atomic.AtomicBoolean @Serializable(OfflineMessageSourceImplData.Serializer::class) -internal data class OfflineMessageSourceImplData( +internal class OfflineMessageSourceImplData( override val kind: MessageSourceKind, override val ids: IntArray, override val botId: Long, override val time: Int, override val fromId: Long, override val targetId: Long, - override val originalMessage: MessageChain, + originalMessageLazy: Lazy, override val internalIds: IntArray, ) : OfflineMessageSource(), MessageSourceInternal { object Serializer : MessageSourceSerializerImpl("OfflineMessageSource") override val sequenceIds: IntArray get() = ids + override val originalMessage: MessageChain by originalMessageLazy // for override. // if provided, no need to serialize from message @@ -81,6 +82,7 @@ internal data class OfflineMessageSourceImplData( if (time != other.time) return false if (fromId != other.fromId) return false if (targetId != other.targetId) return false + // TODO: 2021-01-09: 解决 QuoteReply 的 MessageSource 因为 originalMessage 造成的死循环 if (originalMessage != other.originalMessage) return false if (!internalIds.contentEquals(other.internalIds)) return false @@ -94,6 +96,7 @@ internal data class OfflineMessageSourceImplData( result = 31 * result + time result = 31 * result + fromId.hashCode() result = 31 * result + targetId.hashCode() + // TODO: 2021-01-09: 解决 QuoteReply 的 MessageSource 因为 originalMessage 造成的死循环 result = 31 * result + originalMessage.hashCode() result = 31 * result + internalIds.contentHashCode() return result @@ -139,6 +142,25 @@ internal fun OfflineMessageSourceImplData( } } +internal fun OfflineMessageSourceImplData( + kind: MessageSourceKind, + ids: IntArray, + botId: Long, + time: Int, + fromId: Long, + targetId: Long, + originalMessage: MessageChain, + internalIds: IntArray, +): OfflineMessageSourceImplData = OfflineMessageSourceImplData( + kind = kind, + ids = ids, + botId = botId, + time = time, + fromId = fromId, + targetId = targetId, + originalMessageLazy = lazyOf(originalMessage), + internalIds = internalIds +) internal fun OfflineMessageSourceImplData( delegate: ImMsgBody.SourceMsg, @@ -151,7 +173,7 @@ internal fun OfflineMessageSourceImplData( internalIds = delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()) .origUids?.mapToIntArray { it.toInt() } ?: intArrayOf(), time = delegate.time, - originalMessage = delegate.toMessageChain(botId, groupIdOrZero), + originalMessageLazy = lazy { delegate.toMessageChain(botId, groupIdOrZero) }, fromId = delegate.senderUin, targetId = when { groupIdOrZero != 0L -> groupIdOrZero