From f04c623658b013bdf50b43cd7ea7df25b576c50f Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Sat, 17 Dec 2022 22:36:38 +0000 Subject: [PATCH] [core] Implement a more efficient algorithm to fetch roaming messages for group: - Added `RoamingMessagesImplGroup`. - Dump API changes for Group RoamingMessages. - [mock] Fix MockRoamingMessages missing MessageSource - [core] Convert hierarchical TimeBasedRoamingMessagesImpl to common, to reduce code complexity --- .../android/api/android.api | 2 +- .../compatibility-validation/jvm/api/jvm.api | 2 +- .../src/database/MessageDatabase.kt | 27 +++- .../contact/roaming/MockRoamingMessages.kt | 3 +- mirai-core-mock/test/mock/MessagingTest.kt | 44 ++++-- .../roaming/RoamingMessagesImplGroup.kt | 125 +++++++++--------- .../roaming/SeqBasedRoamingMessageImpl.kt | 71 ---------- .../roaming/TimeBasedRoamingMessagesImpl.kt | 6 +- .../kotlin/message/ReceiveMessageHandler.kt | 26 ++-- .../protocol/packet/chat/TroopManagement.kt | 6 +- .../roaming/TimeBasedRoamingMessagesImpl.kt | 51 ------- .../roaming/TimeBasedRoamingMessagesImpl.kt | 13 -- 12 files changed, 143 insertions(+), 233 deletions(-) delete mode 100644 mirai-core/src/commonMain/kotlin/contact/roaming/SeqBasedRoamingMessageImpl.kt delete mode 100644 mirai-core/src/jvmBaseMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt delete mode 100644 mirai-core/src/nativeMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt diff --git a/mirai-core-api/compatibility-validation/android/api/android.api b/mirai-core-api/compatibility-validation/android/api/android.api index fcbfaa216..5da4649da 100644 --- a/mirai-core-api/compatibility-validation/android/api/android.api +++ b/mirai-core-api/compatibility-validation/android/api/android.api @@ -366,7 +366,7 @@ public abstract interface class net/mamoe/mirai/contact/Friend : kotlinx/corouti public abstract fun setRemark (Ljava/lang/String;)V } -public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutines/CoroutineScope, net/mamoe/mirai/contact/AudioSupported, net/mamoe/mirai/contact/Contact, net/mamoe/mirai/contact/FileSupported { +public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutines/CoroutineScope, net/mamoe/mirai/contact/AudioSupported, net/mamoe/mirai/contact/Contact, net/mamoe/mirai/contact/FileSupported, net/mamoe/mirai/contact/roaming/RoamingSupported { public static final field Companion Lnet/mamoe/mirai/contact/Group$Companion; public fun avatarUrl (Lnet/mamoe/mirai/contact/AvatarSpec;)Ljava/lang/String; public abstract fun contains (J)Z diff --git a/mirai-core-api/compatibility-validation/jvm/api/jvm.api b/mirai-core-api/compatibility-validation/jvm/api/jvm.api index 5654ef39c..98c58ede2 100644 --- a/mirai-core-api/compatibility-validation/jvm/api/jvm.api +++ b/mirai-core-api/compatibility-validation/jvm/api/jvm.api @@ -366,7 +366,7 @@ public abstract interface class net/mamoe/mirai/contact/Friend : kotlinx/corouti public abstract fun setRemark (Ljava/lang/String;)V } -public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutines/CoroutineScope, net/mamoe/mirai/contact/AudioSupported, net/mamoe/mirai/contact/Contact, net/mamoe/mirai/contact/FileSupported { +public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutines/CoroutineScope, net/mamoe/mirai/contact/AudioSupported, net/mamoe/mirai/contact/Contact, net/mamoe/mirai/contact/FileSupported, net/mamoe/mirai/contact/roaming/RoamingSupported { public static final field Companion Lnet/mamoe/mirai/contact/Group$Companion; public fun avatarUrl (Lnet/mamoe/mirai/contact/AvatarSpec;)Ljava/lang/String; public abstract fun contains (J)Z diff --git a/mirai-core-mock/src/database/MessageDatabase.kt b/mirai-core-mock/src/database/MessageDatabase.kt index a9861b932..61612760e 100644 --- a/mirai-core-mock/src/database/MessageDatabase.kt +++ b/mirai-core-mock/src/database/MessageDatabase.kt @@ -11,9 +11,7 @@ package net.mamoe.mirai.mock.database import net.mamoe.mirai.contact.Contact import net.mamoe.mirai.contact.roaming.RoamingMessageFilter -import net.mamoe.mirai.message.data.MessageChain -import net.mamoe.mirai.message.data.MessageSource -import net.mamoe.mirai.message.data.MessageSourceKind +import net.mamoe.mirai.message.data.* import net.mamoe.mirai.mock.MockBot import net.mamoe.mirai.mock.internal.db.MsgDatabaseImpl import net.mamoe.mirai.utils.concatAsLong @@ -80,6 +78,29 @@ public data class MessageInfo( public val time: Long, // seconds public val message: MessageChain, ) { + public fun buildSource(bot: MockBot): MessageSource { + return bot.buildMessageSource(kind = kind) { + val info = this@MessageInfo + sender(info.sender) + time(info.time.toInt()) + + if (kind == MessageSourceKind.GROUP) { + target(subject) + } else { + if (info.sender == info.subject) { + target(bot.id) + } else { + target(info.subject) + } + } + + ids = intArrayOf(info.id) + internalIds = intArrayOf(info.internal) + + messages(info.message as Iterable<Message>) + } + } + // ids public val id: Int get() = (mixinedMsgId shr 32).toInt() diff --git a/mirai-core-mock/src/internal/contact/roaming/MockRoamingMessages.kt b/mirai-core-mock/src/internal/contact/roaming/MockRoamingMessages.kt index d1cd7b21c..7eede5366 100644 --- a/mirai-core-mock/src/internal/contact/roaming/MockRoamingMessages.kt +++ b/mirai-core-mock/src/internal/contact/roaming/MockRoamingMessages.kt @@ -20,6 +20,7 @@ import net.mamoe.mirai.contact.roaming.RoamingSupported import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageSourceKind import net.mamoe.mirai.mock.internal.MockBotImpl +import net.mamoe.mirai.mock.utils.mock import net.mamoe.mirai.utils.JavaFriendlyAPI import net.mamoe.mirai.utils.cast import java.util.stream.Stream @@ -54,7 +55,7 @@ internal class MockRoamingMessages( timeStart, timeEnd, filter ?: RoamingMessageFilter.ANY - ).map { it.message } + ).map { it.buildSource(contact.bot.mock()) + it.message } } @JavaFriendlyAPI diff --git a/mirai-core-mock/test/mock/MessagingTest.kt b/mirai-core-mock/test/mock/MessagingTest.kt index 8ffef3c08..78e1fb4f3 100644 --- a/mirai-core-mock/test/mock/MessagingTest.kt +++ b/mirai-core-mock/test/mock/MessagingTest.kt @@ -24,7 +24,7 @@ import kotlin.test.assertFails import kotlin.test.assertNull import kotlin.test.assertSame -internal class MessagingTest: MockBotTestBase() { +internal class MessagingTest : MockBotTestBase() { @Test internal fun testMessageEventBroadcast() = runTest { @@ -133,35 +133,51 @@ internal class MessagingTest: MockBotTestBase() { @Test internal fun testRoamingMessages() = runTest { val mockFriend = bot.addFriend(1, "1") - broadcastMockEvents { - mockFriend says { append("Testing!") } - mockFriend says { append("Test2!") } + + val allSent = mutableListOf<MessageSource>() + fun MutableList<MessageSource>.add(msg: MessageChain) { + add(msg.source) } - mockFriend.sendMessage("Pong!") + + fun MutableList<MessageSource>.convertToOffline() { + replaceAll { src -> + bot.buildMessageSource(src.kind) { allFrom(src) } + } + } + + broadcastMockEvents { + allSent.add(mockFriend says { append("Testing!") }) + allSent.add(mockFriend says { append("Test2!") }) + } + allSent.add(mockFriend.sendMessage("Pong!").source) + allSent.convertToOffline() mockFriend.roamingMessages.getAllMessages().toList().let { messages -> assertEquals(3, messages.size) - assertEquals(messageChainOf(PlainText("Testing!")), messages[0]) - assertEquals(messageChainOf(PlainText("Test2!")), messages[1]) - assertEquals(messageChainOf(PlainText("Pong!")), messages[2]) + assertEquals(messageChainOf(allSent[0] + PlainText("Testing!")), messages[0]) + assertEquals(messageChainOf(allSent[1] + PlainText("Test2!")), messages[1]) + assertEquals(messageChainOf(allSent[2] + PlainText("Pong!")), messages[2]) } + allSent.clear() + val mockGroup = bot.addGroup(2, "2") val mockGroupMember1 = mockGroup.addMember(123, "123") val mockGroupMember2 = mockGroup.addMember(124, "124") val mockGroupMember3 = mockGroup.addMember(125, "125") broadcastMockEvents { - mockGroupMember1 says { append("msg1") } - mockGroupMember2 says { append("msg2") } - mockGroupMember3 says { append("msg3") } + allSent.add(mockGroupMember1 says { append("msg1") }) + allSent.add(mockGroupMember2 says { append("msg2") }) + allSent.add(mockGroupMember3 says { append("msg3") }) } + allSent.convertToOffline() with(mockGroup.roamingMessages.getAllMessages().toList()) { assertEquals(3, size) - assertEquals(messageChainOf(PlainText("msg1")), get(0)) - assertEquals(messageChainOf(PlainText("msg2")), get(1)) - assertEquals(messageChainOf(PlainText("msg3")), get(2)) + assertEquals(messageChainOf(allSent[0] + PlainText("msg1")), get(0)) + assertEquals(messageChainOf(allSent[1] + PlainText("msg2")), get(1)) + assertEquals(messageChainOf(allSent[2] + PlainText("msg3")), get(2)) } } diff --git a/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt b/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt index ed57576f7..677c3f2b8 100644 --- a/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt +++ b/mirai-core/src/commonMain/kotlin/contact/roaming/RoamingMessagesImplGroup.kt @@ -9,79 +9,84 @@ package net.mamoe.mirai.internal.contact.roaming +import kotlinx.coroutines.flow.* +import net.mamoe.mirai.contact.roaming.RoamingMessageFilter import net.mamoe.mirai.internal.contact.CommonGroupImpl +import net.mamoe.mirai.internal.message.getMessageSourceKindFromC2cCmdOrNull +import net.mamoe.mirai.internal.message.toMessageChainOnline import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbGetGroupMsg -import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbGetRoamMsgReq -import net.mamoe.mirai.internal.utils.indexFirstBE +import net.mamoe.mirai.message.data.MessageChain internal class RoamingMessagesImplGroup( override val contact: CommonGroupImpl -) : TimeBasedRoamingMessagesImpl() { - override suspend fun requestRoamMsg( +) : AbstractRoamingMessages() { + private val bot get() = contact.bot + + override suspend fun getMessagesIn( timeStart: Long, - lastMessageTime: Long, - random: Long // unused field - ): MessageSvcPbGetRoamMsgReq.Response { - val lastMsgSeq = contact.bot.network.sendAndExpect( - TroopManagement.GetGroupLastMsgSeq( - client = contact.bot.client, - groupUin = contact.uin - ) - ) - return when (lastMsgSeq) { - is TroopManagement.GetGroupLastMsgSeq.Response.Success -> { - val results = mutableListOf<MsgComm.Msg>() - var currentSeq = lastMsgSeq.seq + timeEnd: Long, + filter: RoamingMessageFilter? + ): Flow<MessageChain> { + var currentSeq: Int = getLastMsgSeq() ?: return emptyFlow() - while (true) { - if (currentSeq <= 0) break - - val resp = contact.bot.network.sendAndExpect( - MessageSvcPbGetGroupMsg( - client = contact.bot.client, - groupUin = contact.uin, - messageSequence = currentSeq, - 20 // maximum 20 - ) + return flow { + while (true) { + val resp = contact.bot.network.sendAndExpect( + MessageSvcPbGetGroupMsg( + client = contact.bot.client, + groupUin = contact.uin, + messageSequence = currentSeq.toLong(), + count = 20 // maximum 20 ) - if (resp is MessageSvcPbGetGroupMsg.Failed) break - if ((resp as MessageSvcPbGetGroupMsg.Success).msgElem.isEmpty()) break - - // the message may be sorted increasing by message time, - // if so, additional sortBy will not take cost. - val msgElems = resp.msgElem.sortedBy { it.msgHead.msgTime } - results.addAll(0, msgElems) - - val firstMsgElem = msgElems.first() - if (firstMsgElem.msgHead.msgTime < timeStart) { - break - } else { - currentSeq = (firstMsgElem.msgHead.msgSeq - 1).toLong() - } - } - - // use binary search to find the first message that message time is lager than lastMessageTime - var right = results.indexFirstBE(lastMessageTime) { it.msgHead.msgTime.toLong() } - // check messages with same time - if (results[right].msgHead.msgTime.toLong() == lastMessageTime) { - do { - right++ - } while (right <= results.size - 1 && results[right].msgHead.msgTime <= lastMessageTime) - } - // loops at most 20 times, just traverse - val left = results.indexOfFirst { it.msgHead.msgTime >= timeStart } - - MessageSvcPbGetRoamMsgReq.Response( - if (left == right) null else results.subList(left, right), - if (left == right) -1L else results[right - 1].msgHead.msgTime.toLong(), -1L, byteArrayOf() ) - } - is TroopManagement.GetGroupLastMsgSeq.Response.Failed -> { - MessageSvcPbGetRoamMsgReq.Response(null, -1L, -1L, byteArrayOf()) + if (resp is MessageSvcPbGetGroupMsg.Failed) break + resp as MessageSvcPbGetGroupMsg.Success // stupid smart cast + if (resp.msgElem.isEmpty()) break + + // the message may be sorted increasing by message time, + // if so, additional sortBy will not take cost. + val messageTimeSequence = resp.msgElem.asSequence().map { it.time } + + val maxTime = messageTimeSequence.max() + + if (maxTime < timeStart) break // we have fetched all messages + + emitAll( + resp.msgElem.asSequence() + .filter { getMessageSourceKindFromC2cCmdOrNull(it.msgHead.c2cCmd) != null } // ignore unsupported messages + .filter { it.time in timeStart..timeEnd } + .sortedByDescending { it.time } // Ensure caller receiver newer messages first + .filter { filter.apply(it) } // Call filter after sort + .asFlow() + .map { it.toMessageChainOnline(bot) } + ) + + currentSeq = resp.msgElem.minBy { it.time }.msgHead.msgSeq } } } + + private val MsgComm.Msg.time get() = msgHead.msgTime + + private fun RoamingMessageFilter?.apply( + it: MsgComm.Msg + ) = this?.invoke(createRoamingMessage(it, listOf())) != false + + private suspend fun getLastMsgSeq(): Int? { + // Iterate from the newest message to find messages within [timeStart] and [timeEnd] + val lastMsgSeqResp = bot.network.sendAndExpect( + TroopManagement.GetGroupLastMsgSeq( + client = bot.client, + groupUin = contact.uin + ) + ) + + return when (lastMsgSeqResp) { + TroopManagement.GetGroupLastMsgSeq.Response.Failed -> null + is TroopManagement.GetGroupLastMsgSeq.Response.Success -> lastMsgSeqResp.seq + } + } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/contact/roaming/SeqBasedRoamingMessageImpl.kt b/mirai-core/src/commonMain/kotlin/contact/roaming/SeqBasedRoamingMessageImpl.kt deleted file mode 100644 index d4b66c315..000000000 --- a/mirai-core/src/commonMain/kotlin/contact/roaming/SeqBasedRoamingMessageImpl.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2019-2022 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. - * - * https://github.com/mamoe/mirai/blob/dev/LICENSE - */ - -package net.mamoe.mirai.internal.contact.roaming - -import kotlinx.coroutines.currentCoroutineContext -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.isActive -import net.mamoe.mirai.contact.roaming.RoamingMessageFilter -import net.mamoe.mirai.internal.message.toMessageChainOnline -import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm -import net.mamoe.mirai.message.data.MessageChain - -private typealias Seq = Long - -internal sealed class SeqBasedRoamingMessageImpl : AbstractRoamingMessages() { - final override suspend fun getMessagesIn( - timeStart: Long, - timeEnd: Long, - filter: RoamingMessageFilter? - ): Flow<MessageChain> { - val (seqStart, seqEnd) = getSeqForTime(timeStart, timeEnd) - return getMessageImpl(seqStart, seqEnd, filter) - } - - protected abstract suspend fun getSeqForTime(timeStart: Long, timeEnd: Long): Pair<Seq, Seq> - - @Suppress("DuplicatedCode") // Generalizing this code would even complicate logic - private suspend fun getMessageImpl( - seqStart: Seq, - seqEnd: Seq, - filter: RoamingMessageFilter?, - ): Flow<MessageChain> { - return flow { - var currentSeqStart = seqEnd.coerceAtMost(seqStart) - while (currentCoroutineContext().isActive) { - val resp = requestRoamMsg(currentSeqStart, seqEnd) - val messages = resp.messages ?: break - if (filter == null || filter === RoamingMessageFilter.ANY) { - // fast path - messages.forEach { emit(it.toMessageChainOnline(contact.bot)) } - } else { - for (message in messages) { - if (filter.invoke(createRoamingMessage(message, messages))) { - emit(message.toMessageChainOnline(contact.bot)) - } - } - } - currentSeqStart = resp.nextSeqStart - } - } - - } - - abstract suspend fun requestRoamMsg( - seqStart: Seq, - seqEnd: Seq, - ): SeqBasedRoamingMessageChunk -} - -internal interface SeqBasedRoamingMessageChunk { - val messages: List<MsgComm.Msg>? - val nextSeqStart: Seq -} diff --git a/mirai-core/src/commonMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt b/mirai-core/src/commonMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt index 35cac6d53..16bf47b79 100644 --- a/mirai-core/src/commonMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt @@ -20,8 +20,7 @@ import net.mamoe.mirai.internal.message.toMessageChainOnline import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbGetRoamMsgReq import net.mamoe.mirai.message.data.MessageChain -// Can't make sealed, used by actuals -internal abstract class CommonTimeBasedRoamingMessagesImpl : AbstractRoamingMessages() { +internal sealed class TimeBasedRoamingMessagesImpl : AbstractRoamingMessages() { override suspend fun getMessagesIn( timeStart: Long, timeEnd: Long, @@ -56,6 +55,3 @@ internal abstract class CommonTimeBasedRoamingMessagesImpl : AbstractRoamingMess random: Long ): MessageSvcPbGetRoamMsgReq.Response } - - -internal expect sealed class TimeBasedRoamingMessagesImpl() : CommonTimeBasedRoamingMessagesImpl \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt b/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt index 904caf201..c9f6a3ab0 100644 --- a/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt +++ b/mirai-core/src/commonMain/kotlin/message/ReceiveMessageHandler.kt @@ -53,21 +53,26 @@ internal suspend fun List<MsgComm.Msg>.toMessageChainOnline( return toMessageChain(bot, groupIdOrZero, true, messageSourceKind, facade).refineDeep(bot, refineContext) } +internal fun getMessageSourceKindFromC2cCmdOrNull(c2cCmd: Int): MessageSourceKind? { + return when (c2cCmd) { + 11 -> MessageSourceKind.FRIEND // bot 给其他人发消息 + 4 -> MessageSourceKind.FRIEND // bot 给自己作为好友发消息 (非 other client) + 1 -> MessageSourceKind.GROUP + else -> null + } +} + +internal fun getMessageSourceKindFromC2cCmd(c2cCmd: Int): MessageSourceKind { + return getMessageSourceKindFromC2cCmdOrNull(c2cCmd) ?: error("Could not get source kind from c2cCmd: $c2cCmd") +} + + internal suspend fun MsgComm.Msg.toMessageChainOnline( bot: Bot, refineContext: RefineContext = EmptyRefineContext, facade: MessageProtocolFacade = MessageProtocolFacade, ): MessageChain { - fun getSourceKind(c2cCmd: Int): MessageSourceKind { - return when (c2cCmd) { - 11 -> MessageSourceKind.FRIEND // bot 给其他人发消息 - 4 -> MessageSourceKind.FRIEND // bot 给自己作为好友发消息 (非 other client) - 1 -> MessageSourceKind.GROUP - else -> error("Could not get source kind from c2cCmd: $c2cCmd") - } - } - - val kind = getSourceKind(msgHead.c2cCmd) + val kind = getMessageSourceKindFromC2cCmd(msgHead.c2cCmd) val groupId = when (kind) { MessageSourceKind.GROUP -> msgHead.groupInfo?.groupCode ?: 0 else -> 0 @@ -141,6 +146,7 @@ internal object ReceiveMessageTransformer { MessageSourceKind.STRANGER -> OnlineMessageSourceFromStrangerImpl(bot, messageList) } } + false -> { OfflineMessageSourceImplData(bot, messageList, messageSourceKind) } diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt index 1c6d6ea41..36a914def 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt @@ -466,14 +466,14 @@ internal class TroopManagement { } internal object GetGroupLastMsgSeq : OutgoingPacketFactory<GetGroupLastMsgSeq.Response>("OidbSvc.0x88d_0") { - sealed class Response(val groupUin: Long, val seq: Long) : Packet { + sealed class Response(val groupUin: Long, val seq: Int) : Packet { object Failed : Response(-1, -1) { override fun toString(): String { return "TroopManagement.GetGroupLastMsgSeq.Failed" } } - class Success(groupUin: Long, seq: Long) : Response(groupUin, seq) { + class Success(groupUin: Long, seq: Int) : Response(groupUin, seq) { override fun toString(): String { return "TroopManagement.GetGroupLastMsgSeq.Response(groupUin=${groupUin}, seq=${seq})" } @@ -511,7 +511,7 @@ internal class TroopManagement { val info = group.stgroupinfo ?: return Response.Failed val seq = info.groupCurMsgSeq ?: return Response.Failed - return Response.Success(group.groupCode, seq.toLong()) + return Response.Success(group.groupCode, seq) } } } \ No newline at end of file diff --git a/mirai-core/src/jvmBaseMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt b/mirai-core/src/jvmBaseMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt deleted file mode 100644 index c3b5c6095..000000000 --- a/mirai-core/src/jvmBaseMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2019-2022 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. - * - * https://github.com/mamoe/mirai/blob/dev/LICENSE - */ - -package net.mamoe.mirai.internal.contact.roaming - -import kotlinx.coroutines.runBlocking -import net.mamoe.mirai.contact.roaming.RoamingMessageFilter -import net.mamoe.mirai.internal.message.toMessageChainOnline -import net.mamoe.mirai.message.data.MessageChain -import net.mamoe.mirai.utils.JavaFriendlyAPI -import net.mamoe.mirai.utils.stream -import java.util.stream.Stream - -internal actual sealed class TimeBasedRoamingMessagesImpl : CommonTimeBasedRoamingMessagesImpl() { - @JavaFriendlyAPI - override suspend fun getMessagesStream( - timeStart: Long, - timeEnd: Long, - filter: RoamingMessageFilter?, - ): Stream<MessageChain> { - return stream { - var lastMessageTime = timeEnd - var random = 0L - while (true) { - val resp = runBlocking { - requestRoamMsg(timeStart, lastMessageTime, random) - } - - val messages = resp.messages ?: break - if (filter == null || filter === RoamingMessageFilter.ANY) { - messages.forEach { yield(runBlocking { it.toMessageChainOnline(contact.bot) }) } - } else { - for (message in messages) { - if (filter.invoke(createRoamingMessage(message, messages))) { - yield(runBlocking { message.toMessageChainOnline(contact.bot) }) - } - } - } - - lastMessageTime = resp.lastMessageTime - random = resp.random - } - } - } -} \ No newline at end of file diff --git a/mirai-core/src/nativeMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt b/mirai-core/src/nativeMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt deleted file mode 100644 index 2b04f0d37..000000000 --- a/mirai-core/src/nativeMain/kotlin/contact/roaming/TimeBasedRoamingMessagesImpl.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2019-2022 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. - * - * https://github.com/mamoe/mirai/blob/dev/LICENSE - */ - -package net.mamoe.mirai.internal.contact.roaming - -internal actual sealed class TimeBasedRoamingMessagesImpl actual constructor() : - CommonTimeBasedRoamingMessagesImpl() \ No newline at end of file