From b738d7b9514ca319599c1bd6d627b3b1561733fd Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Tue, 25 Feb 2025 19:11:16 +0800 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=20OneBotGroup.?= =?UTF-8?q?send=20=E7=9A=84=E6=8B=A6=E6=88=AA=E4=BA=8B=E4=BB=B6=E5=92=8C?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E5=9B=9E=E8=B0=83=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../build.gradle.kts | 3 +- .../api/simbot-component-onebot-v11-core.api | 61 ++++++++ .../build.gradle.kts | 8 +- .../core/actor/internal/OneBotGroupImpl.kt | 141 ++++++++++++++++-- .../v11/core/bot/internal/OneBotBotImpl.kt | 35 +++-- .../v11/core/event/OneBotInternalEvent.kt | 43 ++++++ .../OneBotGroupInteractionEventImpls.kt | 75 ++++++++++ .../OneBotInternalMessageInteractionEvent.kt | 52 +++++++ .../OneBotSegmentsInteractionMessage.kt | 116 ++++++++++++++ .../OneBotSendSupportInteractionEvent.kt | 116 ++++++++++++++ .../onebot/v11/core/utils/MessageResolvers.kt | 2 +- .../onebot/v11/core/utils/MessageUtil.kt | 8 + .../core/event/GroupSendInteractionTests.kt | 126 ++++++++++++++++ .../build.gradle.kts | 5 +- .../build.gradle.kts | 8 +- 15 files changed, 768 insertions(+), 31 deletions(-) create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/OneBotInternalEvent.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotGroupInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt diff --git a/simbot-component-onebot-common/build.gradle.kts b/simbot-component-onebot-common/build.gradle.kts index 0543833f..70a7e140 100644 --- a/simbot-component-onebot-common/build.gradle.kts +++ b/simbot-component-onebot-common/build.gradle.kts @@ -51,7 +51,7 @@ kotlin { sourceSets { commonMain.dependencies { implementation(libs.simbot.api) - implementation(libs.simbot.common.annotations) + api(libs.simbot.common.annotations) } commonTest.dependencies { @@ -61,6 +61,7 @@ kotlin { jvmMain { dependencies { + compileOnly(libs.simbot.api) } } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api index d234f225..e872e968 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api @@ -2140,6 +2140,16 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public fun getTime ()Llove/forte/simbot/common/time/Timestamp; } +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/OneBotInternalEvent : love/forte/simbot/component/onebot/v11/core/event/OneBotCommonEvent, love/forte/simbot/event/InternalEvent { +} + +public class love/forte/simbot/component/onebot/v11/core/event/OneBotInternalInterceptionException : love/forte/simbot/event/InternalInterceptionException { + public fun ()V + public fun (Ljava/lang/String;)V + public fun (Ljava/lang/String;Ljava/lang/Throwable;)V + public fun (Ljava/lang/Throwable;)V +} + public final class love/forte/simbot/component/onebot/v11/core/event/OneBotUnknownEvent : love/forte/simbot/component/onebot/v11/core/event/OneBotEvent { public fun (Ljava/lang/String;Llove/forte/simbot/component/onebot/v11/event/UnknownEvent;)V public final fun component1 ()Ljava/lang/String; @@ -2296,6 +2306,57 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public fun getSubType ()Ljava/lang/String; } +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent, love/forte/simbot/event/ChatGroupInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotGroup; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupPostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPostSendEvent, love/forte/simbot/event/ChatGroupPostSendEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotGroup; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupPreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPreSendEvent, love/forte/simbot/event/ChatGroupPreSendEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotGroup; + public abstract fun getCurrentMessage ()Llove/forte/simbot/event/InteractionMessage; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; + public abstract fun setCurrentMessage (Llove/forte/simbot/event/InteractionMessage;)V +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent : love/forte/simbot/event/InternalMessageInteractionEvent { +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessagePostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent { +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessagePreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent { +} + +public final class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage : love/forte/simbot/event/InteractionMessage$Extension { + public static final field Companion Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage$Companion; + public synthetic fun (Llove/forte/simbot/event/InteractionMessage;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public static final fun create (Llove/forte/simbot/event/InteractionMessage;Ljava/util/List;)Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; + public fun equals (Ljava/lang/Object;)Z + public final fun getMessage ()Llove/forte/simbot/event/InteractionMessage; + public final fun getSegments ()Ljava/util/List; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage$Companion { + public final fun create (Llove/forte/simbot/event/InteractionMessage;Ljava/util/List;)Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; + public static synthetic fun create$default (Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage$Companion;Llove/forte/simbot/event/InteractionMessage;Ljava/util/List;ILjava/lang/Object;)Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent, love/forte/simbot/event/SendSupportInteractionEvent { + public abstract fun getBot ()Llove/forte/simbot/component/onebot/v11/core/bot/OneBotBot; + public abstract fun getContent ()Llove/forte/simbot/ability/SendSupport; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent, love/forte/simbot/event/SendSupportPostSendEvent { +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent, love/forte/simbot/event/SendSupportPreSendEvent { +} + public abstract interface class love/forte/simbot/component/onebot/v11/core/event/meta/OneBotHeartbeatEvent : love/forte/simbot/component/onebot/v11/core/event/meta/OneBotMetaEvent { public fun getIntervalMilliseconds ()J public abstract fun getSourceEvent ()Llove/forte/simbot/component/onebot/v11/event/meta/RawHeartbeatEvent; diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/build.gradle.kts b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/build.gradle.kts index cef3f5e0..8791ef4f 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/build.gradle.kts +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/build.gradle.kts @@ -60,8 +60,12 @@ kotlin { sourceSets { commonMain.dependencies { + // JVM compileOnly implementation(libs.simbot.api) - implementation(libs.simbot.common.annotations) + implementation(libs.jetbrains.annotations) + + api(libs.simbot.common.annotations) + implementation(libs.simbot.common.atomic) api(project(":simbot-component-onebot-common")) api(project(":simbot-component-onebot-v11:simbot-component-onebot-v11-common")) @@ -88,7 +92,9 @@ kotlin { jvmMain { dependencies { + compileOnly(libs.simbot.api) compileOnly(libs.ktor.client.contentNegotiation) + compileOnly(libs.jetbrains.annotations) } } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt index 2ff40a19..045c07d5 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt @@ -27,14 +27,21 @@ import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroupDeleteOption import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember import love.forte.simbot.component.onebot.v11.core.api.* import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotGroupPostSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotGroupPreSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList import love.forte.simbot.component.onebot.v11.core.utils.sendGroupMsgApi import love.forte.simbot.component.onebot.v11.core.utils.sendGroupTextMsgApi import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt +import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment +import love.forte.simbot.event.InteractionMessage import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent +import love.forte.simbot.message.PlainText import kotlin.concurrent.Volatile import kotlin.coroutines.CoroutineContext import kotlin.jvm.JvmInline @@ -87,34 +94,123 @@ internal abstract class OneBotGroupImpl( } override suspend fun send(text: String): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage.create( + message = InteractionMessage.valueOf(text), + segments = null + ) + + return interceptionAndSend(interactionMessage) + } + + override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage.create( + message = InteractionMessage.valueOf(messageContent), + segments = (messageContent as? OneBotMessageContent)?.sourceSegments + ) + + return interceptionAndSend(interactionMessage) + } + + override suspend fun send(message: Message): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage.create( + message = InteractionMessage.valueOf(message), + segments = message.resolveToOneBotSegmentList(bot) + ) + + return interceptionAndSend(interactionMessage) + } + + private suspend fun interceptionAndSend( + interactionMessage: OneBotSegmentsInteractionMessage + ): OneBotMessageReceipt { + val event = OneBotGroupPreSendEventImpl( + this, + bot, + interactionMessage + ) + + bot.emitMessagePreSendEvent(event) + val currentMessage = event.useCurrentMessage() + val segments = (currentMessage as? OneBotSegmentsInteractionMessage)?.segments + if (segments != null) { + return sendSegments(segments).toReceipt(bot).alsoPostSend(currentMessage) + } + + return sendByInteractionMessage(currentMessage).toReceipt(bot).alsoPostSend(currentMessage) + } + + /** + * 解析一个 InteractionMessage 为一个 OneBotMessageSegment 的列表并发送。 + * 始终认为 `segments` 为 `null`。 + */ + private suspend fun sendByInteractionMessage( + interactionMessage: InteractionMessage, + allowSegmentMessage: Boolean = true + ): SendMsgResult { + return when (interactionMessage) { + is InteractionMessage.Message -> sendMessage(interactionMessage.message) + is InteractionMessage.MessageContent -> { + val messageContent = interactionMessage.messageContent + if (messageContent is OneBotMessageContent) { + sendSegments(messageContent.sourceSegments) + } else { + sendMessage(messageContent.messages) + } + } + + is InteractionMessage.Text -> sendText(interactionMessage.text) + is OneBotSegmentsInteractionMessage -> { + if (!allowSegmentMessage) { + error( + "InteractionMessage.message does not support the type OneBotSegmentsInteractionMessage, " + + "but $interactionMessage" + ) + } + + sendByInteractionMessage(interactionMessage.message, false) + } + + else -> error("Unknown InteractionMessage type: $interactionMessage") + } + } + + + private suspend fun sendText(text: String): SendMsgResult { return bot.executeData( sendGroupTextMsgApi( target = id, text = text, ) - ).toReceipt(bot) + ) } - override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { - if (messageContent is OneBotMessageContent) { - return bot.executeData( - sendGroupMsgApi( - target = id, - message = messageContent.sourceSegments, - ) - ).toReceipt(bot) + private suspend fun sendMessage(message: Message): SendMsgResult { + return when (message) { + is PlainText -> sendText(message.text) + else -> sendSegments(message.resolveToOneBotSegmentList(bot)) } - - return send(messageContent.messages) } - override suspend fun send(message: Message): OneBotMessageReceipt { + private suspend fun sendSegments(segments: List): SendMsgResult { return bot.executeData( sendGroupMsgApi( target = id, - message = message.resolveToOneBotSegmentList(bot) + message = segments, ) - ).toReceipt(bot) + ) + } + + private fun OneBotMessageReceipt.alsoPostSend( + interactionMessage: InteractionMessage + ): OneBotMessageReceipt = apply { + val event = OneBotGroupPostSendEventImpl( + content = this@OneBotGroupImpl, + bot = bot, + receipt = this, + message = interactionMessage.toOneBotSegmentsInteractionMessage() + ) + + bot.pushEventAndLaunch(event) } override suspend fun delete(vararg options: DeleteOption) { @@ -206,6 +302,23 @@ internal abstract class OneBotGroupImpl( bot.executeData(GetGroupHonorInfoApi.create(groupId = id, type = type)) override fun toString(): String = "OneBotGroup(id=$id, bot=${bot.id})" + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is OneBotGroupImpl) return false + + if (name != other.name) return false + if (bot != other.bot) return false + + return true + } + + override fun hashCode(): Int { + var result = name.hashCode() + result = 31 * result + bot.hashCode() + return result + } + + } /** diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotImpl.kt index 25ca0772..924dd516 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotImpl.kt @@ -24,9 +24,7 @@ import io.ktor.client.statement.* import io.ktor.http.* import io.ktor.websocket.* import kotlinx.coroutines.* -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.serialization.SerializationException @@ -54,8 +52,12 @@ import love.forte.simbot.component.onebot.v11.core.actor.internal.toGroup import love.forte.simbot.component.onebot.v11.core.actor.internal.toMember import love.forte.simbot.component.onebot.v11.core.actor.internal.toStranger import love.forte.simbot.component.onebot.v11.core.api.* -import love.forte.simbot.component.onebot.v11.core.bot.* +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotConfiguration +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotFriendRelation +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotGroupRelation import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component +import love.forte.simbot.component.onebot.v11.core.event.OneBotInternalInterceptionException import love.forte.simbot.component.onebot.v11.core.event.OneBotUnknownEvent import love.forte.simbot.component.onebot.v11.core.event.OneBotUnsupportedEvent import love.forte.simbot.component.onebot.v11.core.event.internal.message.* @@ -78,9 +80,7 @@ import love.forte.simbot.component.onebot.v11.event.request.RawGroupRequestEvent import love.forte.simbot.component.onebot.v11.event.resolveEventSerializer import love.forte.simbot.component.onebot.v11.event.resolveEventSubTypeFieldName import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent -import love.forte.simbot.event.Event -import love.forte.simbot.event.EventProcessor -import love.forte.simbot.event.EventResult +import love.forte.simbot.event.* import love.forte.simbot.logger.LoggerFactory import kotlin.concurrent.Volatile import kotlin.coroutines.CoroutineContext @@ -299,7 +299,6 @@ internal class OneBotBotImpl( return WsEventSession(wsClient, host) } - private inner class WsEventSession( val wsClient: HttpClient, val wsHost: Url @@ -643,12 +642,30 @@ internal class OneBotBotImpl( return pushEvent(resolveRawEventToEvent(rawEvent, event)) } - private fun pushEvent(event: Event): Flow { + internal fun pushEvent(event: Event): Flow { return eventProcessor .push(event) .onEachErrorLog(logger) } + internal fun pushEventAndLaunch(event: Event): Job { + return pushEvent(event).launchIn(this) + } + + internal suspend fun emitMessagePreSendEvent(event: InternalMessagePreSendEvent) { + val errors = eventProcessor + .push(event) + .filterIsInstance() + .toList() + + if (errors.isNotEmpty()) { + val ex = OneBotInternalInterceptionException("Internal message pre send event process failed") + errors.forEach { ex.addSuppressed(it.content) } + logger.error("Internal message pre send event process failed", ex) + throw ex + } + } + override fun toString(): String = "OneBotBot(uniqueId='$uniqueId', isStarted=$isStarted, isActive=$isActive)" } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/OneBotInternalEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/OneBotInternalEvent.kt new file mode 100644 index 00000000..753909e5 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/OneBotInternalEvent.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event + +import love.forte.simbot.event.FuzzyEventTypeImplementation +import love.forte.simbot.event.InternalEvent +import love.forte.simbot.event.InternalInterceptionException + + +/** + * OneBot组件中实现 [InternalEvent] 的内部事件类型。 + * + * 内部事件通常与真实的事件无关,是一些用于内部流转的通知或拦截事件。 + * + * @since 1.6.0 + * + * @author ForteScarlet + */ +@SubclassOptInRequired(FuzzyEventTypeImplementation::class) +public interface OneBotInternalEvent : OneBotCommonEvent, InternalEvent + + +public open class OneBotInternalInterceptionException : InternalInterceptionException { + public constructor() : super() + public constructor(message: String?) : super(message) + public constructor(message: String?, cause: Throwable?) : super(message, cause) + public constructor(cause: Throwable?) : super(cause) +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotGroupInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotGroupInteractionEventImpls.kt new file mode 100644 index 00000000..73915572 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotGroupInteractionEventImpls.kt @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.annotations.ExperimentalSimbotAPI +import love.forte.simbot.common.atomic.atomic +import love.forte.simbot.common.id.ID +import love.forte.simbot.common.id.UUID +import love.forte.simbot.common.time.Timestamp +import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroup +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupPostSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupPreSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt +import love.forte.simbot.event.InteractionMessage + +internal class OneBotGroupPreSendEventImpl( + override val content: OneBotGroup, + override val bot: OneBotBot, + override val message: OneBotSegmentsInteractionMessage +) : OneBotGroupPreSendEvent { + override val id: ID = UUID.random() + + @OptIn(ExperimentalSimbotAPI::class) + override val time: Timestamp = Timestamp.now() + + private val currentMessageUsed = atomic(false) + + private var _currentMessage: InteractionMessage = message + + override var currentMessage: InteractionMessage + get() = _currentMessage + set(value) { + if (currentMessageUsed.value) { + error("`currentMessage` has been used.") + } + _currentMessage = value + } + + internal fun useCurrentMessage(): InteractionMessage { + if (!currentMessageUsed.compareAndSet(false, true)) { + error("`currentMessage` has been used.") + } + + return _currentMessage + } +} + +internal class OneBotGroupPostSendEventImpl( + override val content: OneBotGroup, + override val bot: OneBotBot, + override val receipt: OneBotMessageReceipt, + override val message: OneBotSegmentsInteractionMessage +) : OneBotGroupPostSendEvent { + override val id: ID = UUID.random() + + @OptIn(ExperimentalSimbotAPI::class) + override val time: Timestamp = Timestamp.now() +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt new file mode 100644 index 00000000..6bf96121 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.messageinteraction + +import love.forte.simbot.event.FuzzyEventTypeImplementation +import love.forte.simbot.event.InternalMessageInteractionEvent +import love.forte.simbot.message.Message + +/** + * OneBot 组件中与 [Message] 交互有关的事件。 + * + * @since 4.6.0 + * + * @author ForteScarlet + */ +@SubclassOptInRequired(FuzzyEventTypeImplementation::class) +public interface OneBotInternalMessageInteractionEvent : InternalMessageInteractionEvent + +/** + * OneBot 组件针对消息发送前的拦截事件。 + * + * @since 4.6.0 + * + * @author ForteScarlet + */ +@SubclassOptInRequired(FuzzyEventTypeImplementation::class) +public interface OneBotInternalMessagePreSendEvent : OneBotInternalMessageInteractionEvent + +/** + * OneBot 组件针对消息发送后的通知事件。 + * + * @since 4.6.0 + * + * @author ForteScarlet + */ +@SubclassOptInRequired(FuzzyEventTypeImplementation::class) +public interface OneBotInternalMessagePostSendEvent : OneBotInternalMessageInteractionEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt new file mode 100644 index 00000000..f95213e9 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.messageinteraction + +import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment +import love.forte.simbot.event.InteractionMessage +import kotlin.jvm.JvmStatic + + +/** + * OneBot组件中同时存在源 [Message] 和 [OneBotMessageSegment] 列表的 [InteractionMessage] 扩展类型。 + * + * @since 1.6.0 + * @author ForteScarlet + */ +public class OneBotSegmentsInteractionMessage private constructor( + /** + * 消息发送时提供的原入参,只可能是 [InteractionMessage.Text], + * [InteractionMessage.Message] 或 + * [InteractionMessage.MessageContent]。 + */ + public val message: InteractionMessage, + + /** + * 一个 [OneBotMessageSegment] 的列表。 + * + * ## 接收时 + * + * 当通过事件获取到 [OneBotSegmentsInteractionMessage] 时: + * - 如果 [message] 为 [InteractionMessage.Text] 时, + * 代表发送纯文本消息,不需要解析 `segments`, 此时 [segments] 为 `null`。 + * + * ## 构建时 + * + * 如果打算通过构建 [OneBotSegmentsInteractionMessage] 用于篡改消息发送的内容: + * + * - 如果 [segments] 不为 `null`, 则会始终直接使用 [segments] 中的内容,不再有额外解析。 + * - 如果 [segments] 为 `null`, 则会根据 [message] 的类型进行解析,仅支持 [InteractionMessage.Text], + * [InteractionMessage.Message] 或 + * [InteractionMessage.MessageContent],如果出现其他类型的 [InteractionMessage] 则会抛出异常。 + */ + public val segments: List?, +) : InteractionMessage.Extension() { + public companion object { + /** + * 构建一个 [OneBotSegmentsInteractionMessage] 实例。 + * + * @param message 当 [segments] 为 `null` 时,可用于解析 [segments] 的 [InteractionMessage]。 + * 如果要被用于解析,请确保 [message] 的类型为 [InteractionMessage.Text], + * [InteractionMessage.Message] 或 + * [InteractionMessage.MessageContent]。 + * + * @throws IllegalArgumentException 如果 [message] 的类型不是 [InteractionMessage.Text], + * [InteractionMessage.Message] 或 + * [InteractionMessage.MessageContent]。 + */ + @JvmStatic + public fun create( + message: InteractionMessage, + segments: List? = null + ): OneBotSegmentsInteractionMessage { + if (segments == null) { + require( + message is Text || + message is Message || + message is MessageContent + ) { + "`message` only support InteractionMessage.Text, " + + "InteractionMessage.Message or " + + "InteractionMessage.MessageContent, but $message" + } + } + return OneBotSegmentsInteractionMessage(message, segments) + } + } + + override fun toString(): String { + return "OneBotSegmentsInteractionMessage(message=$message, segments=$segments)" + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is OneBotSegmentsInteractionMessage) return false + + if (message != other.message) return false + if (segments != other.segments) return false + + return true + } + + override fun hashCode(): Int { + var result = message.hashCode() + result = 31 * result + (segments?.hashCode() ?: 0) + return result + } +} + +internal fun InteractionMessage.toOneBotSegmentsInteractionMessage(): OneBotSegmentsInteractionMessage { + return this as? OneBotSegmentsInteractionMessage + ?: OneBotSegmentsInteractionMessage.create(this, null) +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt new file mode 100644 index 00000000..33658c0b --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.messageinteraction + +import love.forte.simbot.ability.SendSupport +import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroup +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.event.* + + +/** + * OneBot组件中针对 [SendSupport] 的拦截或通知事件。 + * + * @see love.forte.simbot.component.onebot.v11.core.actor.OneBotFriend + * @see love.forte.simbot.component.onebot.v11.core.actor.OneBotGroup + * @see love.forte.simbot.component.onebot.v11.core.actor.OneBotMember + * + * @since 1.6.0 + * + * @author ForteScarlet + */ +@SubclassOptInRequired(FuzzyEventTypeImplementation::class) +public interface OneBotSendSupportInteractionEvent : + SendSupportInteractionEvent, + OneBotInternalMessageInteractionEvent { + override val bot: OneBotBot + override val content: SendSupport +} + +/** + * OneBot组件中针对 [SendSupport.send] 的拦截事件。 + * 可以对其中的参数进行修改。 + * + * @since 1.6.0 + * @author ForteScarlet + */ +@SubclassOptInRequired(FuzzyEventTypeImplementation::class) +public interface OneBotSendSupportPreSendEvent : SendSupportPreSendEvent, OneBotSendSupportInteractionEvent + +/** + * OneBot组件中针对 [SendSupport.send] 的通知事件。 + * 会在 [SendSupport.send] 执行成功后带着它的相关结果进行异步通知。 + * + * @since 1.6.0 + * @author ForteScarlet + */ +@SubclassOptInRequired(FuzzyEventTypeImplementation::class) +public interface OneBotSendSupportPostSendEvent : SendSupportPostSendEvent, OneBotSendSupportInteractionEvent + +//region OneBotGroup + +/** + * OneBot组件针对 [OneBotGroup] 的交互事件。 + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotGroupInteractionEvent : OneBotSendSupportInteractionEvent, ChatGroupInteractionEvent { + override val content: OneBotGroup +} + +/** + * OneBot组件针对 [OneBotGroup.send] 的拦截事件。 + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotGroupPreSendEvent : + OneBotSendSupportPreSendEvent, + OneBotGroupInteractionEvent, + ChatGroupPreSendEvent { + override val content: OneBotGroup + + /** + * 拦截事件中的消息内容。 + */ + override val message: OneBotSegmentsInteractionMessage + + /** + * 可修改的 [message],初始为 [message], + * 修改后会在事件处理完成后被替换为原本的参数。 + * + * 如果被设置为 [OneBotSegmentsInteractionMessage] + * 之外的类型,效果同设置了一个 [OneBotSegmentsInteractionMessage.segments] 为 `null` 的值, + * 最终都会在需要的情况下重新解析 [OneBotSegmentsInteractionMessage.segments]。 + */ + override var currentMessage: InteractionMessage +} + +/** + * OneBot组件针对 [OneBotGroup.send] 的通知事件。 + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotGroupPostSendEvent : + OneBotSendSupportPostSendEvent, + OneBotGroupInteractionEvent, + ChatGroupPostSendEvent { + override val content: OneBotGroup +} +//endregion + + diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageResolvers.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageResolvers.kt index 19d0a279..036f6b98 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageResolvers.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageResolvers.kt @@ -22,7 +22,7 @@ import love.forte.simbot.component.onebot.v11.message.resolveToOneBotSegmentList import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment import love.forte.simbot.message.Message -internal suspend fun Message.resolveToOneBotSegmentList( +internal fun Message.resolveToOneBotSegmentList( bot: OneBotBot, ): List = resolveToOneBotSegmentList( defaultImageAdditionalParams = bot.configuration.defaultImageAdditionalParamsProvider diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageUtil.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageUtil.kt index 376b6998..b2ef04db 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageUtil.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageUtil.kt @@ -24,6 +24,7 @@ import love.forte.simbot.component.onebot.v11.core.api.SendMsgApi import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment import love.forte.simbot.component.onebot.v11.message.segment.OneBotReply import love.forte.simbot.component.onebot.v11.message.segment.OneBotText +import org.jetbrains.annotations.ApiStatus /** * 构建一个用于发送的纯文本消息。 @@ -31,6 +32,7 @@ import love.forte.simbot.component.onebot.v11.message.segment.OneBotText * @param messageType see [SendMsgApi]`.MESSAGE_TYPE_*` */ @InternalOneBotAPI +@ApiStatus.Internal public fun sendTextMsgApi( messageType: String, target: ID, @@ -61,6 +63,7 @@ public fun sendTextMsgApi( } @InternalOneBotAPI +@ApiStatus.Internal public fun sendPrivateTextMsgApi( target: ID, text: String, @@ -73,6 +76,7 @@ public fun sendPrivateTextMsgApi( ) @InternalOneBotAPI +@ApiStatus.Internal public fun sendGroupTextMsgApi( target: ID, text: String, @@ -91,6 +95,7 @@ public fun sendGroupTextMsgApi( * @param messageType see [SendMsgApi]`.MESSAGE_TYPE_*` */ @InternalOneBotAPI +@ApiStatus.Internal public fun sendMsgApi( messageType: String, target: ID, @@ -118,6 +123,7 @@ public fun sendMsgApi( } @InternalOneBotAPI +@ApiStatus.Internal public fun resolveReplyMessageSegmentList( message: List, reply: ID, @@ -139,6 +145,7 @@ public fun resolveReplyMessageSegmentList( } @InternalOneBotAPI +@ApiStatus.Internal public fun sendPrivateMsgApi( target: ID, message: List, @@ -151,6 +158,7 @@ public fun sendPrivateMsgApi( ) @InternalOneBotAPI +@ApiStatus.Internal public fun sendGroupMsgApi( target: ID, message: List, diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt new file mode 100644 index 00000000..3550f4cc --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt @@ -0,0 +1,126 @@ +package love.forte.simbot.component.onebot.v11.core.event + +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk +import io.mockk.spyk +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.runBlocking +import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.overwriteWith +import love.forte.simbot.common.id.IntID.Companion.ID +import love.forte.simbot.common.id.UUID +import love.forte.simbot.component.onebot.common.annotations.ApiResultConstructor +import love.forte.simbot.component.onebot.v11.core.OneBot11 +import love.forte.simbot.component.onebot.v11.core.actor.internal.OneBotGroupApiResultImpl +import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotConfiguration +import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.core.application.launchSimpleApplication +import love.forte.simbot.event.EventDispatcher +import love.forte.simbot.event.EventListener +import love.forte.simbot.event.InteractionMessage +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertIs + + +/** + * + * @author ForteScarlet + */ +@OptIn(ApiResultConstructor::class) +class GroupSendInteractionTests { + private fun spykBot(dispatcher: EventDispatcher): OneBotBotImpl { + return spyk( + OneBotBotImpl( + "1234", + EmptyCoroutineContext, + SupervisorJob(), + OneBotBotConfiguration(), + OneBot11Component(), + dispatcher, + Json(OneBot11.DefaultJson) { + serializersModule = serializersModule overwriteWith OneBot11.serializersModule + } + ), + recordPrivateCalls = true + ) + } + + @Test + fun testSendTextInterception() { + val bot: OneBotBotImpl = spykBot(mockk()) + val group = spyk( + OneBotGroupApiResultImpl( + source = mockk(relaxed = true), + bot = bot, + ownerId = UUID.random() + ), + ) + + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + runBlocking { group.send("Hello World") } + + coVerify { group.send("Hello World") } + coVerify { + bot.emitMessagePreSendEvent( + match { + it.message is OneBotSegmentsInteractionMessage && + (it.message as? OneBotSegmentsInteractionMessage)?.message is InteractionMessage.Text && + (it.message as? OneBotSegmentsInteractionMessage)?.segments == null + } + ) + } + } + + @Test + fun testSendTextInterceptionExceptionCollection() { + val app = runBlocking { launchSimpleApplication() } + + val l1 = EventListener { throw IllegalStateException("ERROR1") } + val l2 = EventListener { throw IllegalArgumentException("ERROR2") } + + app.eventDispatcher.register(l1) + app.eventDispatcher.register(l2) + + val dispatcher = spyk(app.eventDispatcher, recordPrivateCalls = true) + + val bot = spykBot(dispatcher) + + val group = spyk( + OneBotGroupApiResultImpl( + source = mockk(relaxed = true), + bot = bot, + ownerId = UUID.random() + ), + ) + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + val error = assertFailsWith { + runBlocking { group.send("Hello World") } + } + + assertEquals(2, error.suppressed.size) + assertIs(error.suppressed[0]) + assertEquals("ERROR1", error.suppressed[0].message) + assertIs(error.suppressed[1]) + assertEquals("ERROR2", error.suppressed[1].message) + + coVerify { group.send("Hello World") } + coVerify { + bot.emitMessagePreSendEvent( + match { + it.message is OneBotSegmentsInteractionMessage && + (it.message as? OneBotSegmentsInteractionMessage)?.message is InteractionMessage.Text && + (it.message as? OneBotSegmentsInteractionMessage)?.segments == null + } + ) + } + } +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-event/build.gradle.kts b/simbot-component-onebot-v11/simbot-component-onebot-v11-event/build.gradle.kts index 0c2eefdf..1469f2b3 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-event/build.gradle.kts +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-event/build.gradle.kts @@ -55,9 +55,9 @@ kotlin { sourceSets { commonMain.dependencies { implementation(libs.simbot.api) - implementation(libs.simbot.common.annotations) + api(libs.simbot.common.annotations) + api(project(":simbot-component-onebot-common")) implementation(libs.kotlinx.serialization.json) - implementation(project(":simbot-component-onebot-common")) api(project(":simbot-component-onebot-v11:simbot-component-onebot-v11-common")) api(project(":simbot-component-onebot-v11:simbot-component-onebot-v11-message")) @@ -73,6 +73,7 @@ kotlin { jvmMain { dependencies { + compileOnly(libs.simbot.api) } } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-message/build.gradle.kts b/simbot-component-onebot-v11/simbot-component-onebot-v11-message/build.gradle.kts index 25640547..59c337a7 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-message/build.gradle.kts +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-message/build.gradle.kts @@ -58,11 +58,12 @@ kotlin { sourceSets { commonMain.dependencies { - implementation(project(":simbot-component-onebot-common")) implementation(libs.simbot.api) - implementation(libs.simbot.common.annotations) - implementation(libs.kotlinx.io.core) + api(project(":simbot-component-onebot-common")) + api(libs.simbot.common.annotations) + api(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.io.core) implementation(libs.kotlinx.serialization.json) implementation(libs.jetbrains.annotations) } @@ -76,6 +77,7 @@ kotlin { jvmMain { dependencies { + compileOnly(libs.simbot.api) compileOnly(libs.jetbrains.annotations) } } From f01ec9cade7e919771c3faef9696ff81b6216505 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 26 Feb 2025 15:13:51 +0800 Subject: [PATCH 02/11] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=20OneBotGroup.?= =?UTF-8?q?send=20=E7=9A=84=E6=8B=A6=E6=88=AA=E4=BA=8B=E4=BB=B6=E5=92=8C?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E5=9B=9E=E8=B0=83=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/event/GroupSendInteractionTests.kt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt index 3550f4cc..8808e5ec 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt @@ -4,8 +4,10 @@ import io.mockk.coEvery import io.mockk.coVerify import io.mockk.mockk import io.mockk.spyk +import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json import kotlinx.serialization.modules.overwriteWith import love.forte.simbot.common.id.IntID.Companion.ID @@ -17,16 +19,20 @@ import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotConfiguration import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupPostSendEvent import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage import love.forte.simbot.core.application.launchSimpleApplication import love.forte.simbot.event.EventDispatcher import love.forte.simbot.event.EventListener import love.forte.simbot.event.InteractionMessage +import love.forte.simbot.event.process +import love.forte.simbot.message.MessageReceipt import kotlin.coroutines.EmptyCoroutineContext import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertIs +import kotlin.test.assertSame /** @@ -123,4 +129,34 @@ class GroupSendInteractionTests { ) } } + + @Test + fun testGroupPostSend() = runTest { + val app = launchSimpleApplication() + + val receiptFromEvent = CompletableDeferred() + + app.eventDispatcher.process { event -> + receiptFromEvent.complete(event.receipt) + } + + val dispatcher = spyk(app.eventDispatcher, recordPrivateCalls = true) + + val bot = spykBot(dispatcher) + + val group = spyk( + OneBotGroupApiResultImpl( + source = mockk(relaxed = true), + bot = bot, + ownerId = UUID.random() + ), + ) + + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + val receiptFromSend = group.send("Hello World") + + coVerify { group.send("Hello World") } + + assertSame(receiptFromSend, receiptFromEvent.await()) + } } From 972669acebd1828f09008b36c8214696d789a879 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 26 Feb 2025 17:19:57 +0800 Subject: [PATCH 03/11] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=20OneBotFriend?= =?UTF-8?q?.send=20=E7=9A=84=E6=8B=A6=E6=88=AA=E4=BA=8B=E4=BB=B6=E5=92=8C?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E5=9B=9E=E8=B0=83=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/actor/internal/OneBotFriendImpl.kt | 95 +++++++-- .../core/actor/internal/OneBotGroupImpl.kt | 64 ++---- .../AbstractInteractionEventImpls.kt | 66 ++++++ .../OneBotFriendInteractionEventImpls.kt | 38 ++++ .../OneBotGroupInteractionEventImpls.kt | 43 +--- .../OneBotInternalMessageInteractionEvent.kt | 10 +- .../OneBotSegmentsInteractionMessage.kt | 49 ++++- .../OneBotSendSupportInteractionEvent.kt | 50 +++++ .../onebot/v11/core/utils/MessageUtil.kt | 88 ++++++++ .../core/event/FriendSendInteractionTests.kt | 197 ++++++++++++++++++ .../core/event/GroupSendInteractionTests.kt | 60 +++++- 11 files changed, 632 insertions(+), 128 deletions(-) create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/AbstractInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotFriendInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/FriendSendInteractionTests.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt index ca60aaa9..a3df9379 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt @@ -23,50 +23,109 @@ import love.forte.simbot.component.onebot.v11.core.actor.OneBotStranger import love.forte.simbot.component.onebot.v11.core.api.GetFriendListResult import love.forte.simbot.component.onebot.v11.core.api.GetStrangerInfoApi import love.forte.simbot.component.onebot.v11.core.api.SendLikeApi +import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotFriendPostSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotFriendPreSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.segmentsOrNull +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt -import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList -import love.forte.simbot.component.onebot.v11.core.utils.sendPrivateMsgApi -import love.forte.simbot.component.onebot.v11.core.utils.sendPrivateTextMsgApi +import love.forte.simbot.component.onebot.v11.core.utils.* import love.forte.simbot.component.onebot.v11.event.message.RawPrivateMessageEvent -import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt +import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment +import love.forte.simbot.event.InteractionMessage import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent +import love.forte.simbot.message.PlainText import kotlin.coroutines.CoroutineContext internal abstract class OneBotFriendImpl : OneBotFriend { protected abstract val bot: OneBotBotImpl override suspend fun send(text: String): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(text = text) + return interceptionAndSend(interactionMessage) + } + + override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(content = messageContent) + return interceptionAndSend(interactionMessage) + } + + override suspend fun send(message: Message): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(message = message, bot = bot) + return interceptionAndSend(interactionMessage) + } + + private suspend fun interceptionAndSend( + interactionMessage: OneBotSegmentsInteractionMessage + ): OneBotMessageReceipt { + val event = OneBotFriendPreSendEventImpl( + this, + bot, + interactionMessage + ) + + val currentMessage = bot.emitMessagePreSendEventAndUseCurrentMessage(event) + val segments = currentMessage.segmentsOrNull + if (segments != null) { + return sendSegments(segments).toReceipt(bot).alsoPostSend(currentMessage) + } + + return sendByInteractionMessage(currentMessage).toReceipt(bot).alsoPostSend(currentMessage) + } + + /** + * 解析一个 [InteractionMessage] 为一个 [OneBotMessageSegment] 的列表并发送。 + * 始终认为 `segments` 为 `null`。 + */ + private suspend fun sendByInteractionMessage(interactionMessage: InteractionMessage): SendMsgResult { + return resolveInteractionMessage( + interactionMessage = interactionMessage, + onSegments = { sendSegments(it) }, + onMessage = { sendMessage(it) }, + onText = { sendText(it) }, + ) + } + + private suspend fun sendText(text: String): SendMsgResult { return bot.executeData( sendPrivateTextMsgApi( target = id, text = text, ) - ).toReceipt(bot) + ) } - override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { - if (messageContent is OneBotMessageContent) { - return bot.executeData( - sendPrivateMsgApi( - target = id, - message = messageContent.sourceSegments, - ) - ).toReceipt(bot) + private suspend fun sendMessage(message: Message): SendMsgResult { + return when (message) { + is PlainText -> sendText(message.text) + else -> sendSegments(message.resolveToOneBotSegmentList(bot)) } - - return send(messageContent.messages) } - override suspend fun send(message: Message): OneBotMessageReceipt { + private suspend fun sendSegments(segments: List): SendMsgResult { return bot.executeData( sendPrivateMsgApi( target = id, - message = message.resolveToOneBotSegmentList(bot) + message = segments, ) - ).toReceipt(bot) + ) + } + + private fun OneBotMessageReceipt.alsoPostSend( + interactionMessage: InteractionMessage + ): OneBotMessageReceipt = apply { + val event = OneBotFriendPostSendEventImpl( + content = this@OneBotFriendImpl, + bot = bot, + receipt = this, + message = interactionMessage.toOneBotSegmentsInteractionMessage() + ) + + bot.pushEventAndLaunch(event) } override suspend fun sendLike(times: Int) { diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt index 045c07d5..c58e3b0c 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt @@ -30,12 +30,14 @@ import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotGroupPostSendEventImpl import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotGroupPreSendEventImpl import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.segmentsOrNull import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt +import love.forte.simbot.component.onebot.v11.core.utils.emitMessagePreSendEventAndUseCurrentMessage +import love.forte.simbot.component.onebot.v11.core.utils.resolveInteractionMessage import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList import love.forte.simbot.component.onebot.v11.core.utils.sendGroupMsgApi import love.forte.simbot.component.onebot.v11.core.utils.sendGroupTextMsgApi -import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment import love.forte.simbot.event.InteractionMessage @@ -94,29 +96,17 @@ internal abstract class OneBotGroupImpl( } override suspend fun send(text: String): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage.create( - message = InteractionMessage.valueOf(text), - segments = null - ) - + val interactionMessage = OneBotSegmentsInteractionMessage(text) return interceptionAndSend(interactionMessage) } override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage.create( - message = InteractionMessage.valueOf(messageContent), - segments = (messageContent as? OneBotMessageContent)?.sourceSegments - ) - + val interactionMessage = OneBotSegmentsInteractionMessage(messageContent) return interceptionAndSend(interactionMessage) } override suspend fun send(message: Message): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage.create( - message = InteractionMessage.valueOf(message), - segments = message.resolveToOneBotSegmentList(bot) - ) - + val interactionMessage = OneBotSegmentsInteractionMessage(message = message, bot = bot) return interceptionAndSend(interactionMessage) } @@ -129,9 +119,8 @@ internal abstract class OneBotGroupImpl( interactionMessage ) - bot.emitMessagePreSendEvent(event) - val currentMessage = event.useCurrentMessage() - val segments = (currentMessage as? OneBotSegmentsInteractionMessage)?.segments + val currentMessage = bot.emitMessagePreSendEventAndUseCurrentMessage(event) + val segments = currentMessage.segmentsOrNull if (segments != null) { return sendSegments(segments).toReceipt(bot).alsoPostSend(currentMessage) } @@ -143,38 +132,15 @@ internal abstract class OneBotGroupImpl( * 解析一个 InteractionMessage 为一个 OneBotMessageSegment 的列表并发送。 * 始终认为 `segments` 为 `null`。 */ - private suspend fun sendByInteractionMessage( - interactionMessage: InteractionMessage, - allowSegmentMessage: Boolean = true - ): SendMsgResult { - return when (interactionMessage) { - is InteractionMessage.Message -> sendMessage(interactionMessage.message) - is InteractionMessage.MessageContent -> { - val messageContent = interactionMessage.messageContent - if (messageContent is OneBotMessageContent) { - sendSegments(messageContent.sourceSegments) - } else { - sendMessage(messageContent.messages) - } - } - - is InteractionMessage.Text -> sendText(interactionMessage.text) - is OneBotSegmentsInteractionMessage -> { - if (!allowSegmentMessage) { - error( - "InteractionMessage.message does not support the type OneBotSegmentsInteractionMessage, " + - "but $interactionMessage" - ) - } - - sendByInteractionMessage(interactionMessage.message, false) - } - - else -> error("Unknown InteractionMessage type: $interactionMessage") - } + private suspend fun sendByInteractionMessage(interactionMessage: InteractionMessage): SendMsgResult { + return resolveInteractionMessage( + interactionMessage = interactionMessage, + onSegments = { sendSegments(it) }, + onMessage = { sendMessage(it) }, + onText = { sendText(it) }, + ) } - private suspend fun sendText(text: String): SendMsgResult { return bot.executeData( sendGroupTextMsgApi( diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/AbstractInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/AbstractInteractionEventImpls.kt new file mode 100644 index 00000000..151f64ac --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/AbstractInteractionEventImpls.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.annotations.ExperimentalSimbotAPI +import love.forte.simbot.common.atomic.atomic +import love.forte.simbot.common.id.ID +import love.forte.simbot.common.id.UUID +import love.forte.simbot.common.time.Timestamp +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotInternalMessagePostSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotInternalMessagePreSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.event.FuzzyEventTypeImplementation +import love.forte.simbot.event.InteractionMessage + + +@OptIn(FuzzyEventTypeImplementation::class) +internal abstract class AbstractMessagePreSendEventImpl(override val message: OneBotSegmentsInteractionMessage) : + OneBotInternalMessagePreSendEvent { + override val id: ID = UUID.random() + + @OptIn(ExperimentalSimbotAPI::class) + override val time: Timestamp = Timestamp.now() + + protected val currentMessageUsed = atomic(false) + private var _currentMessage: InteractionMessage = message + + override var currentMessage: InteractionMessage + get() = _currentMessage + set(value) { + if (currentMessageUsed.value) { + error("`currentMessage` has been used.") + } + _currentMessage = value + } + + internal fun useCurrentMessage(): InteractionMessage { + if (!currentMessageUsed.compareAndSet(false, true)) { + error("`currentMessage` has been used.") + } + return _currentMessage + } +} + +@OptIn(FuzzyEventTypeImplementation::class) +internal abstract class AbstractMessagePostSendEventImpl : OneBotInternalMessagePostSendEvent { + override val id: ID = UUID.random() + + @OptIn(ExperimentalSimbotAPI::class) + override val time: Timestamp = Timestamp.now() +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotFriendInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotFriendInteractionEventImpls.kt new file mode 100644 index 00000000..c6bf5549 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotFriendInteractionEventImpls.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.component.onebot.v11.core.actor.OneBotFriend +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotFriendPostSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotFriendPreSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt + +internal class OneBotFriendPreSendEventImpl( + override val content: OneBotFriend, + override val bot: OneBotBot, + message: OneBotSegmentsInteractionMessage +) : AbstractMessagePreSendEventImpl(message), OneBotFriendPreSendEvent + +internal class OneBotFriendPostSendEventImpl( + override val content: OneBotFriend, + override val bot: OneBotBot, + override val receipt: OneBotMessageReceipt, + override val message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePostSendEventImpl(), OneBotFriendPostSendEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotGroupInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotGroupInteractionEventImpls.kt index 73915572..82965deb 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotGroupInteractionEventImpls.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotGroupInteractionEventImpls.kt @@ -17,59 +17,22 @@ package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction -import love.forte.simbot.annotations.ExperimentalSimbotAPI -import love.forte.simbot.common.atomic.atomic -import love.forte.simbot.common.id.ID -import love.forte.simbot.common.id.UUID -import love.forte.simbot.common.time.Timestamp import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroup import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupPostSendEvent import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupPreSendEvent import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt -import love.forte.simbot.event.InteractionMessage internal class OneBotGroupPreSendEventImpl( override val content: OneBotGroup, override val bot: OneBotBot, - override val message: OneBotSegmentsInteractionMessage -) : OneBotGroupPreSendEvent { - override val id: ID = UUID.random() - - @OptIn(ExperimentalSimbotAPI::class) - override val time: Timestamp = Timestamp.now() - - private val currentMessageUsed = atomic(false) - - private var _currentMessage: InteractionMessage = message - - override var currentMessage: InteractionMessage - get() = _currentMessage - set(value) { - if (currentMessageUsed.value) { - error("`currentMessage` has been used.") - } - _currentMessage = value - } - - internal fun useCurrentMessage(): InteractionMessage { - if (!currentMessageUsed.compareAndSet(false, true)) { - error("`currentMessage` has been used.") - } - - return _currentMessage - } -} + message: OneBotSegmentsInteractionMessage +) : AbstractMessagePreSendEventImpl(message), OneBotGroupPreSendEvent internal class OneBotGroupPostSendEventImpl( override val content: OneBotGroup, override val bot: OneBotBot, override val receipt: OneBotMessageReceipt, override val message: OneBotSegmentsInteractionMessage -) : OneBotGroupPostSendEvent { - override val id: ID = UUID.random() - - @OptIn(ExperimentalSimbotAPI::class) - override val time: Timestamp = Timestamp.now() -} +) : AbstractMessagePostSendEventImpl(), OneBotGroupPostSendEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt index 6bf96121..452c954d 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt @@ -19,6 +19,8 @@ package love.forte.simbot.component.onebot.v11.core.event.messageinteraction import love.forte.simbot.event.FuzzyEventTypeImplementation import love.forte.simbot.event.InternalMessageInteractionEvent +import love.forte.simbot.event.InternalMessagePostSendEvent +import love.forte.simbot.event.InternalMessagePreSendEvent import love.forte.simbot.message.Message /** @@ -39,7 +41,9 @@ public interface OneBotInternalMessageInteractionEvent : InternalMessageInteract * @author ForteScarlet */ @SubclassOptInRequired(FuzzyEventTypeImplementation::class) -public interface OneBotInternalMessagePreSendEvent : OneBotInternalMessageInteractionEvent +public interface OneBotInternalMessagePreSendEvent : + OneBotInternalMessageInteractionEvent, + InternalMessagePreSendEvent /** * OneBot 组件针对消息发送后的通知事件。 @@ -49,4 +53,6 @@ public interface OneBotInternalMessagePreSendEvent : OneBotInternalMessageIntera * @author ForteScarlet */ @SubclassOptInRequired(FuzzyEventTypeImplementation::class) -public interface OneBotInternalMessagePostSendEvent : OneBotInternalMessageInteractionEvent +public interface OneBotInternalMessagePostSendEvent : + OneBotInternalMessageInteractionEvent, + InternalMessagePostSendEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt index f95213e9..8ee4f843 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt @@ -15,10 +15,20 @@ * If not, see . */ +@file:JvmName("OneBotSegmentsInteractionMessages") +@file:JvmMultifileClass + package love.forte.simbot.component.onebot.v11.core.event.messageinteraction +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList +import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment import love.forte.simbot.event.InteractionMessage +import love.forte.simbot.message.Message +import love.forte.simbot.message.MessageContent +import kotlin.jvm.JvmMultifileClass +import kotlin.jvm.JvmName import kotlin.jvm.JvmStatic @@ -74,16 +84,16 @@ public class OneBotSegmentsInteractionMessage private constructor( message: InteractionMessage, segments: List? = null ): OneBotSegmentsInteractionMessage { - if (segments == null) { - require( + // segments not null or message's type is Text, Message or MessageContent + require( + segments != null || message is Text || - message is Message || - message is MessageContent - ) { - "`message` only support InteractionMessage.Text, " + - "InteractionMessage.Message or " + - "InteractionMessage.MessageContent, but $message" - } + message is Message || + message is MessageContent + ) { + "`message` only support InteractionMessage.Text, " + + "InteractionMessage.Message or " + + "InteractionMessage.MessageContent, but: $message" } return OneBotSegmentsInteractionMessage(message, segments) } @@ -114,3 +124,24 @@ internal fun InteractionMessage.toOneBotSegmentsInteractionMessage(): OneBotSegm return this as? OneBotSegmentsInteractionMessage ?: OneBotSegmentsInteractionMessage.create(this, null) } + +internal fun OneBotSegmentsInteractionMessage(text: String): OneBotSegmentsInteractionMessage { + return OneBotSegmentsInteractionMessage.create(InteractionMessage.valueOf(text), null) +} + +internal fun OneBotSegmentsInteractionMessage(content: MessageContent): OneBotSegmentsInteractionMessage { + return OneBotSegmentsInteractionMessage.create( + message = InteractionMessage.valueOf(content), + segments = (content as? OneBotMessageContent)?.sourceSegments + ) +} + +internal fun OneBotSegmentsInteractionMessage(message: Message, bot: OneBotBot): OneBotSegmentsInteractionMessage { + return OneBotSegmentsInteractionMessage.create( + message = InteractionMessage.valueOf(message), + segments = message.resolveToOneBotSegmentList(bot) + ) +} + +internal inline val InteractionMessage.segmentsOrNull: List? + get() = (this as? OneBotSegmentsInteractionMessage)?.segments diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt index 33658c0b..3e5044a2 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt @@ -18,6 +18,7 @@ package love.forte.simbot.component.onebot.v11.core.event.messageinteraction import love.forte.simbot.ability.SendSupport +import love.forte.simbot.component.onebot.v11.core.actor.OneBotFriend import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroup import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot import love.forte.simbot.event.* @@ -113,4 +114,53 @@ public interface OneBotGroupPostSendEvent : } //endregion +//region OneBotFriend +/** + * OneBot组件针对 [OneBotFriend] 的交互事件。 + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotFriendInteractionEvent : OneBotSendSupportInteractionEvent, ContactInteractionEvent { + override val content: OneBotFriend +} + +/** + * OneBot组件针对 [OneBotFriend.send] 的拦截事件。 + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotFriendPreSendEvent : + OneBotSendSupportPreSendEvent, + OneBotFriendInteractionEvent, + ContactPreSendEvent { + override val content: OneBotFriend + + /** + * 拦截事件中的消息内容。 + */ + override val message: OneBotSegmentsInteractionMessage + + /** + * 可修改的 [message],初始为 [message], + * 修改后会在事件处理完成后被替换为原本的参数。 + * + * 如果被设置为 [OneBotSegmentsInteractionMessage] + * 之外的类型,效果同设置了一个 [OneBotSegmentsInteractionMessage.segments] 为 `null` 的值, + * 最终都会在需要的情况下重新解析 [OneBotSegmentsInteractionMessage.segments]。 + */ + override var currentMessage: InteractionMessage +} + +/** + * OneBot组件针对 [OneBotFriend.send] 的通知事件。 + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotFriendPostSendEvent : + OneBotSendSupportPostSendEvent, + OneBotFriendInteractionEvent, + ContactPostSendEvent { + override val content: OneBotFriend +} +//endregion diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageUtil.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageUtil.kt index b2ef04db..228dee8e 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageUtil.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/MessageUtil.kt @@ -21,9 +21,15 @@ import love.forte.simbot.common.id.ID import love.forte.simbot.component.onebot.common.annotations.InternalOneBotAPI import love.forte.simbot.component.onebot.v11.core.api.OneBotMessageOutgoing import love.forte.simbot.component.onebot.v11.core.api.SendMsgApi +import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.AbstractMessagePreSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment import love.forte.simbot.component.onebot.v11.message.segment.OneBotReply import love.forte.simbot.component.onebot.v11.message.segment.OneBotText +import love.forte.simbot.event.InteractionMessage +import love.forte.simbot.message.Message import org.jetbrains.annotations.ApiStatus /** @@ -169,3 +175,85 @@ public fun sendGroupMsgApi( message = message, reply = reply, ) + + +internal suspend fun OneBotBotImpl.emitMessagePreSendEventAndUseCurrentMessage( + event: AbstractMessagePreSendEventImpl +): InteractionMessage { + emitMessagePreSendEvent(event) + return event.useCurrentMessage() +} + +internal inline fun resolveInteractionMessage( + interactionMessage: InteractionMessage, + allowSegmentMessage: Boolean = true, + onSegments: (List) -> T, + onMessage: (Message) -> T, + onText: (String) -> T, + onOther: (InteractionMessage) -> T = { + error("Unknown InteractionMessage type: $interactionMessage") + }, +): T { + if (!allowSegmentMessage) { + return resolveInteractionMessageDisallowSegmentMessage( + interactionMessage = interactionMessage, + onSegments = onSegments, + onMessage = onMessage, + onText = onText, + onOther = onOther + ) + } + + return when (interactionMessage) { + is InteractionMessage.Message -> onMessage(interactionMessage.message) + is InteractionMessage.MessageContent -> { + val messageContent = interactionMessage.messageContent + if (messageContent is OneBotMessageContent) { + onSegments(messageContent.sourceSegments) + } else { + onMessage(messageContent.messages) + } + } + + is InteractionMessage.Text -> onText(interactionMessage.text) + is OneBotSegmentsInteractionMessage -> resolveInteractionMessageDisallowSegmentMessage( + interactionMessage = interactionMessage.message, + onSegments = onSegments, + onMessage = onMessage, + onText = onText, + onOther = onOther + ) + + else -> onOther(interactionMessage) + } +} + +private inline fun resolveInteractionMessageDisallowSegmentMessage( + interactionMessage: InteractionMessage, + onSegments: (List) -> T, + onMessage: (Message) -> T, + onText: (String) -> T, + onOther: (InteractionMessage) -> T +): T { + return when (interactionMessage) { + is InteractionMessage.Message -> onMessage(interactionMessage.message) + is InteractionMessage.MessageContent -> { + val messageContent = interactionMessage.messageContent + if (messageContent is OneBotMessageContent) { + onSegments(messageContent.sourceSegments) + } else { + onMessage(messageContent.messages) + } + } + + is InteractionMessage.Text -> onText(interactionMessage.text) + is OneBotSegmentsInteractionMessage -> { + error( + "InteractionMessage.message does not support the type OneBotSegmentsInteractionMessage, " + + "but $interactionMessage" + ) + } + + else -> onOther(interactionMessage) + } +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/FriendSendInteractionTests.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/FriendSendInteractionTests.kt new file mode 100644 index 00000000..577dc23a --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/FriendSendInteractionTests.kt @@ -0,0 +1,197 @@ +package love.forte.simbot.component.onebot.v11.core.event + +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk +import io.mockk.spyk +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest +import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.overwriteWith +import love.forte.simbot.common.id.IntID.Companion.ID +import love.forte.simbot.component.onebot.common.annotations.ApiResultConstructor +import love.forte.simbot.component.onebot.v11.core.OneBot11 +import love.forte.simbot.component.onebot.v11.core.actor.internal.OneBotFriendApiResultImpl +import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotConfiguration +import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotFriendPostSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.core.application.launchSimpleApplication +import love.forte.simbot.event.* +import love.forte.simbot.message.MessageReceipt +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.test.* + + +/** + * + * @author ForteScarlet + */ +@OptIn(ApiResultConstructor::class) +class FriendSendInteractionTests { + private fun spykBot(dispatcher: EventDispatcher): OneBotBotImpl { + return spyk( + OneBotBotImpl( + "1234", + EmptyCoroutineContext, + SupervisorJob(), + OneBotBotConfiguration(), + OneBot11Component(), + dispatcher, + Json(OneBot11.DefaultJson) { + serializersModule = serializersModule overwriteWith OneBot11.serializersModule + } + ), + recordPrivateCalls = true + ) + } + + @Test + fun testSendTextInterception() { + val bot: OneBotBotImpl = spykBot(mockk(relaxed = true, relaxUnitFun = true)) + val friend = spyk( + OneBotFriendApiResultImpl( + result = mockk(relaxed = true), + bot = bot, + ), + ) + + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + runBlocking { friend.send("Hello World") } + + coVerify { friend.send("Hello World") } + coVerify { + bot.emitMessagePreSendEvent( + match { + it.message is OneBotSegmentsInteractionMessage && + (it.message as? OneBotSegmentsInteractionMessage)?.message is InteractionMessage.Text && + (it.message as? OneBotSegmentsInteractionMessage)?.segments == null + } + ) + } + } + + @Test + fun testSendTextInterceptionExceptionCollection() { + val app = runBlocking { launchSimpleApplication() } + + val l1 = EventListener { throw IllegalStateException("ERROR1") } + val l2 = EventListener { throw IllegalArgumentException("ERROR2") } + + app.eventDispatcher.register(l1) + app.eventDispatcher.register(l2) + + val dispatcher = spyk(app.eventDispatcher, recordPrivateCalls = true) + + val bot = spykBot(dispatcher) + + val friend = spyk( + OneBotFriendApiResultImpl( + result = mockk(relaxed = true), + bot = bot, + ), + ) + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + val error = assertFailsWith { + runBlocking { friend.send("Hello World") } + } + + assertEquals(2, error.suppressed.size) + assertIs(error.suppressed[0]) + assertEquals("ERROR1", error.suppressed[0].message) + assertIs(error.suppressed[1]) + assertEquals("ERROR2", error.suppressed[1].message) + + coVerify { friend.send("Hello World") } + coVerify { + bot.emitMessagePreSendEvent( + match { + it.message is OneBotSegmentsInteractionMessage && + (it.message as? OneBotSegmentsInteractionMessage)?.message is InteractionMessage.Text && + (it.message as? OneBotSegmentsInteractionMessage)?.segments == null + } + ) + } + } + + @Test + fun testSendTextInterceptionAndModify() { + val app = runBlocking { launchSimpleApplication() } + + app.eventDispatcher.process { event -> + val message = event.message + val currentMessage = event.currentMessage + assertSame(message, currentMessage) + assertIs(message) + assertIs(currentMessage) + assertIs(message.message) + assertEquals("Hello", message.message.text) + assertNull(message.segments) + + event.currentMessage = InteractionMessage.valueOf("Hello World") + } + + val bot = spykBot(app.eventDispatcher) + + val friend = spyk( + OneBotFriendApiResultImpl( + result = mockk(relaxed = true), + bot = bot, + ), + recordPrivateCalls = true + ) + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + runBlocking { friend.send("Hello") } + + coVerify { friend.send("Hello") } + coVerify { + bot.emitMessagePreSendEvent( + match { + it.message is OneBotSegmentsInteractionMessage && + (it.message as? OneBotSegmentsInteractionMessage)?.message is InteractionMessage.Text && + ((it.message as? OneBotSegmentsInteractionMessage)?.message as InteractionMessage.Text) + .text == "Hello" && + (it.message as? OneBotSegmentsInteractionMessage)?.segments == null + } + ) + } + + coVerify { friend invoke "sendText" withArguments listOf("Hello World") } + } + + @Test + fun testFriendPostSend() = runTest { + val app = launchSimpleApplication() + + val receiptFromEvent = CompletableDeferred() + + app.eventDispatcher.process { event -> + receiptFromEvent.complete(event.receipt) + } + + val dispatcher = spyk(app.eventDispatcher, recordPrivateCalls = true) + + val bot = spykBot(dispatcher) + + val friend = spyk( + OneBotFriendApiResultImpl( + result = mockk(relaxed = true), + bot = bot, + ), + ) + + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + val receiptFromSend = friend.send("Hello World") + + coVerify { friend.send("Hello World") } + + assertSame(receiptFromSend, receiptFromEvent.await()) + } +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt index 8808e5ec..d6851874 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupSendInteractionTests.kt @@ -22,17 +22,10 @@ import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupPostSendEvent import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage import love.forte.simbot.core.application.launchSimpleApplication -import love.forte.simbot.event.EventDispatcher -import love.forte.simbot.event.EventListener -import love.forte.simbot.event.InteractionMessage -import love.forte.simbot.event.process +import love.forte.simbot.event.* import love.forte.simbot.message.MessageReceipt import kotlin.coroutines.EmptyCoroutineContext -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertIs -import kotlin.test.assertSame +import kotlin.test.* /** @@ -60,7 +53,7 @@ class GroupSendInteractionTests { @Test fun testSendTextInterception() { - val bot: OneBotBotImpl = spykBot(mockk()) + val bot: OneBotBotImpl = spykBot(mockk(relaxed = true, relaxUnitFun = true)) val group = spyk( OneBotGroupApiResultImpl( source = mockk(relaxed = true), @@ -130,6 +123,53 @@ class GroupSendInteractionTests { } } + @Test + fun testSendTextInterceptionAndModify() { + val app = runBlocking { launchSimpleApplication() } + + app.eventDispatcher.process { event -> + val message = event.message + val currentMessage = event.currentMessage + assertSame(message, currentMessage) + assertIs(message) + assertIs(currentMessage) + assertIs(message.message) + assertEquals("Hello", message.message.text) + assertNull(message.segments) + + event.currentMessage = InteractionMessage.valueOf("Hello World") + } + + val bot = spykBot(app.eventDispatcher) + + val group = spyk( + OneBotGroupApiResultImpl( + source = mockk(relaxed = true), + bot = bot, + ownerId = UUID.random() + ), + recordPrivateCalls = true + ) + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + runBlocking { group.send("Hello") } + + coVerify { group.send("Hello") } + coVerify { + bot.emitMessagePreSendEvent( + match { + it.message is OneBotSegmentsInteractionMessage && + (it.message as? OneBotSegmentsInteractionMessage)?.message is InteractionMessage.Text && + ((it.message as? OneBotSegmentsInteractionMessage)?.message as InteractionMessage.Text) + .text == "Hello" && + (it.message as? OneBotSegmentsInteractionMessage)?.segments == null + } + ) + } + + coVerify { group invoke "sendText" withArguments listOf("Hello World") } + } + @Test fun testGroupPostSend() = runTest { val app = launchSimpleApplication() From ebf683142a1c8abc13316a8fa7f4aab710674f66 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Thu, 27 Feb 2025 17:00:29 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E8=AE=B0=E5=BD=95=E9=83=A8=E5=88=86TODO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OneBotMessageEventInteractionEvent.kt | 44 +++++++++++++++++++ .../OneBotSendSupportInteractionEvent.kt | 8 ++++ 2 files changed, 52 insertions(+) create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt new file mode 100644 index 00000000..c159e034 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.messageinteraction + +import love.forte.simbot.ability.ReplySupport +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.event.FuzzyEventTypeImplementation +import love.forte.simbot.event.MessageEvent +import love.forte.simbot.event.MessageEventInteractionEvent + + +/** + * OneBot组件中针对 [ReplySupport](通常是 [MessageEvent])的拦截或通知事件。 + * + * @see love.forte.simbot.component.onebot.v11.core.event.message.OneBotMessageEvent + * + * @since 1.6.0 + * + * @author ForteScarlet + */ +@SubclassOptInRequired(FuzzyEventTypeImplementation::class) +public interface OneBotMessageEventInteractionEvent : + MessageEventInteractionEvent, + OneBotInternalMessageInteractionEvent { + override val bot: OneBotBot + override val content: MessageEvent +} + +// TODO diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt index 3e5044a2..554b9c39 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt @@ -164,3 +164,11 @@ public interface OneBotFriendPostSendEvent : override val content: OneBotFriend } //endregion + +//region OneBotMember +// TODO +//endregion + +//region OneBotMember +// TODO +//endregion From b60ffba079d30c2a1f4cee848080eb4dc0e8c7ef Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Fri, 28 Feb 2025 15:19:00 +0800 Subject: [PATCH 05/11] =?UTF-8?q?feat:=20`OneBotMember.send`=20=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8B=A6=E6=88=AA=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/actor/internal/OneBotMemberImpl.kt | 94 +++++++-- .../OneBotMemberInteractionEventImpls.kt | 39 ++++ .../OneBotSendSupportInteractionEvent.kt | 39 +++- .../core/event/MemberSendInteractionTests.kt | 197 ++++++++++++++++++ 4 files changed, 347 insertions(+), 22 deletions(-) create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotMemberInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/MemberSendInteractionTests.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt index 805b5468..4872d968 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt @@ -27,16 +27,21 @@ import love.forte.simbot.component.onebot.v11.core.actor.OneBotMemberRole import love.forte.simbot.component.onebot.v11.core.actor.OneBotStranger import love.forte.simbot.component.onebot.v11.core.api.* import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotMemberPostSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotMemberPreSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.segmentsOrNull +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt -import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList -import love.forte.simbot.component.onebot.v11.core.utils.sendPrivateMsgApi -import love.forte.simbot.component.onebot.v11.core.utils.sendPrivateTextMsgApi +import love.forte.simbot.component.onebot.v11.core.utils.* import love.forte.simbot.component.onebot.v11.event.message.RawGroupMessageEvent import love.forte.simbot.component.onebot.v11.event.message.RawPrivateMessageEvent -import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt +import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment +import love.forte.simbot.event.InteractionMessage import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent +import love.forte.simbot.message.PlainText import kotlin.concurrent.Volatile import kotlin.coroutines.CoroutineContext import kotlin.jvm.JvmInline @@ -61,34 +66,87 @@ internal abstract class OneBotMemberImpl( override var nick: String? = initialNick override suspend fun send(text: String): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(text = text) + return interceptionAndSend(interactionMessage) + } + + override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(content = messageContent) + return interceptionAndSend(interactionMessage) + } + + override suspend fun send(message: Message): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(message = message, bot = bot) + return interceptionAndSend(interactionMessage) + } + + private suspend fun interceptionAndSend( + interactionMessage: OneBotSegmentsInteractionMessage + ): OneBotMessageReceipt { + val event = OneBotMemberPreSendEventImpl( + this, + bot, + interactionMessage + ) + + val currentMessage = bot.emitMessagePreSendEventAndUseCurrentMessage(event) + val segments = currentMessage.segmentsOrNull + if (segments != null) { + return sendSegments(segments).toReceipt(bot).alsoPostSend(currentMessage) + } + + return sendByInteractionMessage(currentMessage).toReceipt(bot).alsoPostSend(currentMessage) + } + + /** + * 解析一个 [InteractionMessage] 为一个 [OneBotMessageSegment] 的列表并发送。 + * 始终认为 `segments` 为 `null`。 + */ + private suspend fun sendByInteractionMessage(interactionMessage: InteractionMessage): SendMsgResult { + return resolveInteractionMessage( + interactionMessage = interactionMessage, + onSegments = { sendSegments(it) }, + onMessage = { sendMessage(it) }, + onText = { sendText(it) }, + ) + } + + private suspend fun sendText(text: String): SendMsgResult { return bot.executeData( sendPrivateTextMsgApi( target = id, text = text, ) - ).toReceipt(bot) + ) } - override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { - if (messageContent is OneBotMessageContent) { - return bot.executeData( - sendPrivateMsgApi( - target = id, - message = messageContent.sourceSegments, - ) - ).toReceipt(bot) + private suspend fun sendMessage(message: Message): SendMsgResult { + return when (message) { + is PlainText -> sendText(message.text) + else -> sendSegments(message.resolveToOneBotSegmentList(bot)) } - - return send(messageContent.messages) } - override suspend fun send(message: Message): OneBotMessageReceipt { + private suspend fun sendSegments(segments: List): SendMsgResult { return bot.executeData( sendPrivateMsgApi( target = id, - message = message.resolveToOneBotSegmentList(bot) + message = segments, ) - ).toReceipt(bot) + ) + } + + private fun OneBotMessageReceipt.alsoPostSend( + interactionMessage: InteractionMessage + ): OneBotMessageReceipt = apply { + val event = OneBotMemberPostSendEventImpl( + content = this@OneBotMemberImpl, + bot = bot, + receipt = this, + message = interactionMessage.toOneBotSegmentsInteractionMessage() + ) + + bot.pushEventAndLaunch(event) } override suspend fun delete(vararg options: DeleteOption) { diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotMemberInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotMemberInteractionEventImpls.kt new file mode 100644 index 00000000..44455a8e --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotMemberInteractionEventImpls.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotMemberPostSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotMemberPreSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt + + +internal class OneBotMemberPreSendEventImpl( + override val content: OneBotMember, + override val bot: OneBotBot, + message: OneBotSegmentsInteractionMessage +) : AbstractMessagePreSendEventImpl(message), OneBotMemberPreSendEvent + +internal class OneBotMemberPostSendEventImpl( + override val content: OneBotMember, + override val bot: OneBotBot, + override val receipt: OneBotMessageReceipt, + override val message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePostSendEventImpl(), OneBotMemberPostSendEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt index 554b9c39..1db122cc 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt @@ -20,6 +20,7 @@ package love.forte.simbot.component.onebot.v11.core.event.messageinteraction import love.forte.simbot.ability.SendSupport import love.forte.simbot.component.onebot.v11.core.actor.OneBotFriend import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroup +import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot import love.forte.simbot.event.* @@ -166,9 +167,39 @@ public interface OneBotFriendPostSendEvent : //endregion //region OneBotMember -// TODO -//endregion +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotMemberInteractionEvent : OneBotSendSupportInteractionEvent, MemberInteractionEvent { + override val content: OneBotMember +} -//region OneBotMember -// TODO +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotMemberPreSendEvent : + OneBotSendSupportPreSendEvent, + OneBotMemberInteractionEvent, + MemberPreSendEvent { + override val content: OneBotMember + + /** + * 拦截事件中的消息内容。 + */ + override val message: OneBotSegmentsInteractionMessage + + /** + * 可修改的 [message],初始为 [message], + * 修改后会在事件处理完成后被替换为原本的参数。 + * + * 如果被设置为 [OneBotSegmentsInteractionMessage] + * 之外的类型,效果同设置了一个 [OneBotSegmentsInteractionMessage.segments] 为 `null` 的值, + * 最终都会在需要的情况下重新解析 [OneBotSegmentsInteractionMessage.segments]。 + */ + override var currentMessage: InteractionMessage +} + +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotMemberPostSendEvent : + OneBotSendSupportPostSendEvent, + OneBotMemberInteractionEvent, + MemberPostSendEvent { + override val content: OneBotMember +} //endregion diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/MemberSendInteractionTests.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/MemberSendInteractionTests.kt new file mode 100644 index 00000000..2f7155be --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/MemberSendInteractionTests.kt @@ -0,0 +1,197 @@ +package love.forte.simbot.component.onebot.v11.core.event + +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk +import io.mockk.spyk +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest +import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.overwriteWith +import love.forte.simbot.common.id.IntID.Companion.ID +import love.forte.simbot.component.onebot.common.annotations.ApiResultConstructor +import love.forte.simbot.component.onebot.v11.core.OneBot11 +import love.forte.simbot.component.onebot.v11.core.actor.internal.OneBotMemberApiResultImpl +import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotConfiguration +import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotMemberPostSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.core.application.launchSimpleApplication +import love.forte.simbot.event.* +import love.forte.simbot.message.MessageReceipt +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.test.* + + +/** + * + * @author ForteScarlet + */ +@OptIn(ApiResultConstructor::class) +class MemberSendInteractionTests { + private fun spykBot(dispatcher: EventDispatcher): OneBotBotImpl { + return spyk( + OneBotBotImpl( + "1234", + EmptyCoroutineContext, + SupervisorJob(), + OneBotBotConfiguration(), + OneBot11Component(), + dispatcher, + Json(OneBot11.DefaultJson) { + serializersModule = serializersModule overwriteWith OneBot11.serializersModule + } + ), + recordPrivateCalls = true + ) + } + + @Test + fun testSendTextInterception() { + val bot: OneBotBotImpl = spykBot(mockk(relaxed = true, relaxUnitFun = true)) + val member = spyk( + OneBotMemberApiResultImpl( + source = mockk(relaxed = true), + bot = bot, + ), + ) + + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + runBlocking { member.send("Hello World") } + + coVerify { member.send("Hello World") } + coVerify { + bot.emitMessagePreSendEvent( + match { + it.message is OneBotSegmentsInteractionMessage && + (it.message as? OneBotSegmentsInteractionMessage)?.message is InteractionMessage.Text && + (it.message as? OneBotSegmentsInteractionMessage)?.segments == null + } + ) + } + } + + @Test + fun testSendTextInterceptionExceptionCollection() { + val app = runBlocking { launchSimpleApplication() } + + val l1 = EventListener { throw IllegalStateException("ERROR1") } + val l2 = EventListener { throw IllegalArgumentException("ERROR2") } + + app.eventDispatcher.register(l1) + app.eventDispatcher.register(l2) + + val dispatcher = spyk(app.eventDispatcher, recordPrivateCalls = true) + + val bot = spykBot(dispatcher) + + val member = spyk( + OneBotMemberApiResultImpl( + source = mockk(relaxed = true), + bot = bot, + ), + ) + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + val error = assertFailsWith { + runBlocking { member.send("Hello World") } + } + + assertEquals(2, error.suppressed.size) + assertIs(error.suppressed[0]) + assertEquals("ERROR1", error.suppressed[0].message) + assertIs(error.suppressed[1]) + assertEquals("ERROR2", error.suppressed[1].message) + + coVerify { member.send("Hello World") } + coVerify { + bot.emitMessagePreSendEvent( + match { + it.message is OneBotSegmentsInteractionMessage && + (it.message as? OneBotSegmentsInteractionMessage)?.message is InteractionMessage.Text && + (it.message as? OneBotSegmentsInteractionMessage)?.segments == null + } + ) + } + } + + @Test + fun testSendTextInterceptionAndModify() { + val app = runBlocking { launchSimpleApplication() } + + app.eventDispatcher.process { event -> + val message = event.message + val currentMessage = event.currentMessage + assertSame(message, currentMessage) + assertIs(message) + assertIs(currentMessage) + assertIs(message.message) + assertEquals("Hello", message.message.text) + assertNull(message.segments) + + event.currentMessage = InteractionMessage.valueOf("Hello World") + } + + val bot = spykBot(app.eventDispatcher) + + val member = spyk( + OneBotMemberApiResultImpl( + source = mockk(relaxed = true), + bot = bot, + ), + recordPrivateCalls = true + ) + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + runBlocking { member.send("Hello") } + + coVerify { member.send("Hello") } + coVerify { + bot.emitMessagePreSendEvent( + match { + it.message is OneBotSegmentsInteractionMessage && + (it.message as? OneBotSegmentsInteractionMessage)?.message is InteractionMessage.Text && + ((it.message as? OneBotSegmentsInteractionMessage)?.message as InteractionMessage.Text) + .text == "Hello" && + (it.message as? OneBotSegmentsInteractionMessage)?.segments == null + } + ) + } + + coVerify { member invoke "sendText" withArguments listOf("Hello World") } + } + + @Test + fun testMemberPostSend() = runTest { + val app = launchSimpleApplication() + + val receiptFromEvent = CompletableDeferred() + + app.eventDispatcher.process { event -> + receiptFromEvent.complete(event.receipt) + } + + val dispatcher = spyk(app.eventDispatcher, recordPrivateCalls = true) + + val bot = spykBot(dispatcher) + + val member = spyk( + OneBotMemberApiResultImpl( + source = mockk(relaxed = true), + bot = bot, + ), + ) + + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + val receiptFromSend = member.send("Hello World") + + coVerify { member.send("Hello World") } + + assertSame(receiptFromSend, receiptFromEvent.await()) + } +} From 75bb8ec798b9f4c79e0577e5f8edd4bb200f32b4 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Fri, 28 Feb 2025 16:50:48 +0800 Subject: [PATCH 06/11] =?UTF-8?q?feat:=20`OneBotMessageEvent.reply`=20?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=8B=A6=E6=88=AA=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/simbot-component-onebot-v11-core.api | 95 +++++++++- .../message/OneBotGroupMessageEventImpl.kt | 171 +++++++++++++++--- ...sGroupMessageEventInteractionEventImpls.kt | 38 ++++ ...tGroupMessageEventInteractionEventImpls.kt | 38 ++++ ...lGroupMessageEventInteractionEventImpls.kt | 38 ++++ ...eGroupMessageEventInteractionEventImpls.kt | 38 ++++ .../event/message/OneBotGroupMessageEvent.kt | 2 + .../OneBotMessageEventInteractionEvent.kt | 170 ++++++++++++++++- .../GroupMessageEventInteractionTests.kt | 89 +++++++++ 9 files changed, 648 insertions(+), 31 deletions(-) create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotDefaultGroupMessageEventInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNormalGroupMessageEventInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNoticeGroupMessageEventInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupMessageEventInteractionTests.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api index e872e968..0f1796f1 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api @@ -2306,10 +2306,41 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public fun getSubType ()Ljava/lang/String; } +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent, love/forte/simbot/event/ChatGroupMessageEventInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotAnonymousGroupMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPostReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotAnonymousGroupMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPreReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotAnonymousGroupMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent, love/forte/simbot/event/ContactInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotFriend; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendPostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPostSendEvent, love/forte/simbot/event/ContactPostSendEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotFriend; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendPreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPreSendEvent, love/forte/simbot/event/ContactPreSendEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotFriend; + public abstract fun getCurrentMessage ()Llove/forte/simbot/event/InteractionMessage; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; + public abstract fun setCurrentMessage (Llove/forte/simbot/event/InteractionMessage;)V +} + public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent, love/forte/simbot/event/ChatGroupInteractionEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotGroup; } +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent; +} + public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupPostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPostSendEvent, love/forte/simbot/event/ChatGroupPostSendEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotGroup; } @@ -2324,10 +2355,54 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent : love/forte/simbot/event/InternalMessageInteractionEvent { } -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessagePostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent { +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessagePostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent, love/forte/simbot/event/InternalMessagePostSendEvent { +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessagePreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent, love/forte/simbot/event/InternalMessagePreSendEvent { } -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessagePreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent { +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMemberInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent, love/forte/simbot/event/MemberInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotMember; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMemberPostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMemberInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPostSendEvent, love/forte/simbot/event/MemberPostSendEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotMember; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMemberPreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMemberInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPreSendEvent, love/forte/simbot/event/MemberPreSendEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotMember; + public abstract fun getCurrentMessage ()Llove/forte/simbot/event/InteractionMessage; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; + public abstract fun setCurrentMessage (Llove/forte/simbot/event/InteractionMessage;)V +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent, love/forte/simbot/event/MessageEventInteractionEvent { + public abstract fun getBot ()Llove/forte/simbot/component/onebot/v11/core/bot/OneBotBot; + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent, love/forte/simbot/event/ChatGroupMessageEventInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNormalGroupMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPostReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNormalGroupMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPreReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNormalGroupMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNoticeGroupMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPostReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNoticeGroupMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPreReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNoticeGroupMessageEvent; } public final class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage : love/forte/simbot/event/InteractionMessage$Extension { @@ -2357,6 +2432,22 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent, love/forte/simbot/event/SendSupportPreSendEvent { } +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent, love/forte/simbot/event/MessageEventPostReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent, love/forte/simbot/event/MessageEventPreReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent, love/forte/simbot/event/MessageEventPostReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent, love/forte/simbot/event/MessageEventPreReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent; +} + public abstract interface class love/forte/simbot/component/onebot/v11/core/event/meta/OneBotHeartbeatEvent : love/forte/simbot/component/onebot/v11/core/event/meta/OneBotMetaEvent { public fun getIntervalMilliseconds ()J public abstract fun getSourceEvent ()Llove/forte/simbot/component/onebot/v11/event/meta/RawHeartbeatEvent; diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt index b092c644..abacba25 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt @@ -22,22 +22,29 @@ import love.forte.simbot.common.id.StringID.Companion.ID import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroup import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember import love.forte.simbot.component.onebot.v11.core.actor.internal.toMember +import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl import love.forte.simbot.component.onebot.v11.core.event.internal.eventToString +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.* import love.forte.simbot.component.onebot.v11.core.event.message.OneBotAnonymousGroupMessageEvent import love.forte.simbot.component.onebot.v11.core.event.message.OneBotGroupMessageEvent import love.forte.simbot.component.onebot.v11.core.event.message.OneBotNormalGroupMessageEvent import love.forte.simbot.component.onebot.v11.core.event.message.OneBotNoticeGroupMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OnebotGroupMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.segmentsOrNull +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage import love.forte.simbot.component.onebot.v11.core.internal.message.OneBotMessageContentImpl import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt -import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList -import love.forte.simbot.component.onebot.v11.core.utils.sendGroupMsgApi -import love.forte.simbot.component.onebot.v11.core.utils.sendGroupTextMsgApi +import love.forte.simbot.component.onebot.v11.core.utils.* import love.forte.simbot.component.onebot.v11.event.message.RawGroupMessageEvent import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt +import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment +import love.forte.simbot.event.InteractionMessage import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent +import love.forte.simbot.message.PlainText internal abstract class OneBotGroupMessageEventImpl( sourceEvent: RawGroupMessageEvent, @@ -62,37 +69,85 @@ internal abstract class OneBotGroupMessageEventImpl( } override suspend fun reply(text: String): OneBotMessageReceipt { - val api = sendGroupTextMsgApi( - target = sourceEvent.groupId, - text, - reply = sourceEvent.messageId - ) - - return bot.executeData(api).toReceipt(bot) + val interactionMessage = OneBotSegmentsInteractionMessage(text = text) + return interceptionAndReply(interactionMessage) } override suspend fun reply(messageContent: MessageContent): OneBotMessageReceipt { - if (messageContent is OneBotMessageContent) { - return bot.executeData( - sendGroupMsgApi( - target = sourceEvent.groupId, - message = messageContent.sourceSegments, - reply = sourceEvent.messageId - ) - ).toReceipt(bot) + val interactionMessage = OneBotSegmentsInteractionMessage(content = messageContent) + return interceptionAndReply(interactionMessage) + } + + override suspend fun reply(message: Message): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(message = message, bot = bot) + return interceptionAndReply(interactionMessage) + } + + protected abstract fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): + AbstractMessagePreSendEventImpl + + private suspend fun interceptionAndReply( + interactionMessage: OneBotSegmentsInteractionMessage + ): OneBotMessageReceipt { + val event = preReplyEvent(interactionMessage) + + val currentMessage = bot.emitMessagePreSendEventAndUseCurrentMessage(event) + val segments = currentMessage.segmentsOrNull + if (segments != null) { + return replySegments(segments).toReceipt(bot).alsoPostReply(currentMessage) } - return reply(messageContent.messages) + return replyByInteractionMessage(currentMessage).toReceipt(bot).alsoPostReply(currentMessage) } - override suspend fun reply(message: Message): OneBotMessageReceipt { + /** + * 解析一个 [InteractionMessage] 为一个 [OneBotMessageSegment] 的列表并发送。 + * 始终认为 `segments` 为 `null`。 + */ + private suspend fun replyByInteractionMessage(interactionMessage: InteractionMessage): SendMsgResult { + return resolveInteractionMessage( + interactionMessage = interactionMessage, + onSegments = { replySegments(it) }, + onMessage = { replyMessage(it) }, + onText = { replyText(it) }, + ) + } + + private suspend fun replyText(text: String): SendMsgResult { + return bot.executeData( + sendGroupTextMsgApi( + target = sourceEvent.groupId, + text, + reply = sourceEvent.messageId + ) + ) + } + + private suspend fun replyMessage(message: Message): SendMsgResult { + return when (message) { + is PlainText -> replyText(message.text) + else -> replySegments(message.resolveToOneBotSegmentList(bot)) + } + } + + private suspend fun replySegments(segments: List): SendMsgResult { return bot.executeData( sendGroupMsgApi( target = sourceEvent.groupId, - message = message.resolveToOneBotSegmentList(bot), + message = segments, reply = sourceEvent.messageId ) - ).toReceipt(bot) + ) + } + + protected abstract fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): + OnebotGroupMessageEventPostReplyEvent + + private fun OneBotMessageReceipt.alsoPostReply( + interactionMessage: InteractionMessage + ): OneBotMessageReceipt = apply { + val event = postReplyEvent(interactionMessage) + bot.pushEventAndLaunch(event) } } @@ -106,6 +161,24 @@ internal class OneBotNormalGroupMessageEventImpl( return sourceEvent.sender.toMember(bot, sourceEvent.groupId, sourceEvent.anonymous) } + override fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl { + return OneBotNormalGroupMessageEventPreReplyEventImpl( + bot, + this, + interactionMessage + ) + } + + override fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): + OnebotGroupMessageEventPostReplyEvent { + return OneBotNormalGroupMessageEventPostReplyEventImpl( + bot, + content = this@OneBotNormalGroupMessageEventImpl, + receipt = this, + message = interactionMessage.toOneBotSegmentsInteractionMessage() + ) + } + override fun toString(): String = eventToString("OneBotNormalGroupMessageEvent") } @@ -120,6 +193,24 @@ internal class OneBotAnonymousGroupMessageEventImpl( return sourceEvent.sender.toMember(bot, sourceEvent.groupId, sourceEvent.anonymous) } + override fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl { + return OneBotAnonymousGroupMessageEventPreReplyEventImpl( + bot, + this, + interactionMessage + ) + } + + override fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): + OnebotGroupMessageEventPostReplyEvent { + return OneBotAnonymousGroupMessageEventPostReplyEventImpl( + bot, + content = this@OneBotAnonymousGroupMessageEventImpl, + receipt = this, + message = interactionMessage.toOneBotSegmentsInteractionMessage() + ) + } + override fun toString(): String = eventToString("OneBotAnonymousGroupMessageEvent") } @@ -129,6 +220,24 @@ internal class OneBotNoticeGroupMessageEventImpl( bot: OneBotBotImpl, ) : OneBotGroupMessageEventImpl(sourceEvent, bot), OneBotNoticeGroupMessageEvent { + override fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl { + return OneBotNoticeGroupMessageEventPreReplyEventImpl( + bot, + this, + interactionMessage + ) + } + + override fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): + OnebotGroupMessageEventPostReplyEvent { + return OneBotNoticeGroupMessageEventPostReplyEventImpl( + bot, + content = this@OneBotNoticeGroupMessageEventImpl, + receipt = this, + message = interactionMessage.toOneBotSegmentsInteractionMessage() + ) + } + override fun toString(): String = eventToString("OneBotNoticeGroupMessageEvent") } @@ -138,5 +247,23 @@ internal class OneBotDefaultGroupMessageEventImpl( override val sourceEvent: RawGroupMessageEvent, bot: OneBotBotImpl, ) : OneBotGroupMessageEventImpl(sourceEvent, bot) { + override fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl { + return OneBotDefaultGroupMessageEventPreReplyEventImpl( + bot, + this, + interactionMessage + ) + } + + override fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): + OnebotGroupMessageEventPostReplyEvent { + return OneBotDefaultGroupMessageEventPostReplyEventImpl( + bot, + content = this@OneBotDefaultGroupMessageEventImpl, + receipt = this, + message = interactionMessage.toOneBotSegmentsInteractionMessage() + ) + } + override fun toString(): String = eventToString("OneBotDefaultGroupMessageEvent") } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEventImpls.kt new file mode 100644 index 00000000..e4e83157 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEventImpls.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotAnonymousGroupMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotAnonymousGroupMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotAnonymousGroupMessageEventPreReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.message.MessageReceipt + +internal class OneBotAnonymousGroupMessageEventPreReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotAnonymousGroupMessageEvent, + message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePreSendEventImpl(message), OneBotAnonymousGroupMessageEventPreReplyEvent + +internal class OneBotAnonymousGroupMessageEventPostReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotAnonymousGroupMessageEvent, + override val receipt: MessageReceipt, + override val message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePostSendEventImpl(), OneBotAnonymousGroupMessageEventPostReplyEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotDefaultGroupMessageEventInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotDefaultGroupMessageEventInteractionEventImpls.kt new file mode 100644 index 00000000..9de51b83 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotDefaultGroupMessageEventInteractionEventImpls.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.internal.message.OneBotDefaultGroupMessageEventImpl +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OnebotGroupMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OnebotGroupMessageEventPreReplyEvent +import love.forte.simbot.message.MessageReceipt + +internal class OneBotDefaultGroupMessageEventPreReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotDefaultGroupMessageEventImpl, + message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePreSendEventImpl(message), OnebotGroupMessageEventPreReplyEvent + +internal class OneBotDefaultGroupMessageEventPostReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotDefaultGroupMessageEventImpl, + override val receipt: MessageReceipt, + override val message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePostSendEventImpl(), OnebotGroupMessageEventPostReplyEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNormalGroupMessageEventInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNormalGroupMessageEventInteractionEventImpls.kt new file mode 100644 index 00000000..4b2ab0df --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNormalGroupMessageEventInteractionEventImpls.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotNormalGroupMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotNormalGroupMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotNormalGroupMessageEventPreReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.message.MessageReceipt + +internal class OneBotNormalGroupMessageEventPreReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotNormalGroupMessageEvent, + message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePreSendEventImpl(message), OneBotNormalGroupMessageEventPreReplyEvent + +internal class OneBotNormalGroupMessageEventPostReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotNormalGroupMessageEvent, + override val receipt: MessageReceipt, + override val message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePostSendEventImpl(), OneBotNormalGroupMessageEventPostReplyEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNoticeGroupMessageEventInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNoticeGroupMessageEventInteractionEventImpls.kt new file mode 100644 index 00000000..35c183f0 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNoticeGroupMessageEventInteractionEventImpls.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotNoticeGroupMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotNoticeGroupMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotNoticeGroupMessageEventPreReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.message.MessageReceipt + +internal class OneBotNoticeGroupMessageEventPreReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotNoticeGroupMessageEvent, + message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePreSendEventImpl(message), OneBotNoticeGroupMessageEventPreReplyEvent + +internal class OneBotNoticeGroupMessageEventPostReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotNoticeGroupMessageEvent, + override val receipt: MessageReceipt, + override val message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePostSendEventImpl(), OneBotNoticeGroupMessageEventPostReplyEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent.kt index fd572d3b..960f4d2d 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent.kt @@ -88,6 +88,7 @@ public interface OneBotGroupMessageEvent : OneBotMessageEvent, ChatGroupEvent { * 即 [subType] == `normal` */ @STP +@OptIn(FuzzyEventTypeImplementation::class) public interface OneBotNormalGroupMessageEvent : OneBotGroupMessageEvent, ChatGroupMessageEvent { override val messageContent: OneBotMessageContent override suspend fun content(): OneBotGroup @@ -99,6 +100,7 @@ public interface OneBotNormalGroupMessageEvent : OneBotGroupMessageEvent, ChatGr * 即 [subType] == `anonymous` */ @STP +@OptIn(FuzzyEventTypeImplementation::class) public interface OneBotAnonymousGroupMessageEvent : OneBotGroupMessageEvent, ChatGroupMessageEvent { override val messageContent: OneBotMessageContent override suspend fun content(): OneBotGroup diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt index c159e034..cc99387f 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt @@ -17,15 +17,13 @@ package love.forte.simbot.component.onebot.v11.core.event.messageinteraction -import love.forte.simbot.ability.ReplySupport import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot -import love.forte.simbot.event.FuzzyEventTypeImplementation -import love.forte.simbot.event.MessageEvent -import love.forte.simbot.event.MessageEventInteractionEvent +import love.forte.simbot.component.onebot.v11.core.event.message.* +import love.forte.simbot.event.* /** - * OneBot组件中针对 [ReplySupport](通常是 [MessageEvent])的拦截或通知事件。 + * OneBot组件中针对 [MessageEvent] 的拦截或通知事件。 * * @see love.forte.simbot.component.onebot.v11.core.event.message.OneBotMessageEvent * @@ -38,7 +36,165 @@ public interface OneBotMessageEventInteractionEvent : MessageEventInteractionEvent, OneBotInternalMessageInteractionEvent { override val bot: OneBotBot - override val content: MessageEvent + override val content: OneBotMessageEvent } -// TODO +/** + * OneBot组件中针对 [MessageEvent.reply] 的拦截事件。 + * 可以对其中的参数进行修改。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OnebotMessageEventPreReplyEvent : OneBotMessageEventInteractionEvent, MessageEventPreReplyEvent { + override val content: OneBotMessageEvent +} + +/** + * OneBot组件中针对 [MessageEvent.reply] 的通知事件。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OnebotMessageEventPostReplyEvent : OneBotMessageEventInteractionEvent, MessageEventPostReplyEvent { + override val content: OneBotMessageEvent +} + +//region Group + +/** + * OneBot组件中针对 [ChatGroupMessageEvent] 的拦截或通知事件。 + * + * @since 1.6.0 + * @see love.forte.simbot.component.onebot.v11.core.event.message.OneBotGroupMessageEvent + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotGroupMessageEventInteractionEvent : + OneBotMessageEventInteractionEvent { + override val content: OneBotGroupMessageEvent +} + +/** + * OneBot组件中针对 [ChatGroupMessageEvent.reply] 的拦截事件。 + * 可以对其中的参数进行修改。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OnebotGroupMessageEventPreReplyEvent : + OneBotGroupMessageEventInteractionEvent, + MessageEventPreReplyEvent { + override val content: OneBotGroupMessageEvent +} + +/** + * OneBot组件中针对 [ChatGroupMessageEvent.reply] 的通知事件。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OnebotGroupMessageEventPostReplyEvent : + OneBotGroupMessageEventInteractionEvent, + MessageEventPostReplyEvent { + override val content: OneBotGroupMessageEvent +} + +// OneBotNormalGroupMessageEvent + +/** + * OneBot组件中针对 [OneBotNormalGroupMessageEvent] 的拦截或通知事件。 + * @since 1.6.0 + */ +public interface OneBotNormalGroupMessageEventInteractionEvent : + OneBotGroupMessageEventInteractionEvent, + ChatGroupMessageEventInteractionEvent { + override val content: OneBotNormalGroupMessageEvent +} + +/** + * OneBot组件中针对 [OneBotNormalGroupMessageEvent.reply] 的拦截事件。 + * + * @since 1.6.0 + */ +public interface OneBotNormalGroupMessageEventPreReplyEvent : + OneBotNormalGroupMessageEventInteractionEvent, + OnebotGroupMessageEventPreReplyEvent { + override val content: OneBotNormalGroupMessageEvent +} + +/** + * OneBot组件中针对 [OneBotNormalGroupMessageEvent.reply] 的通知事件。 + * @since 1.6.0 + */ +public interface OneBotNormalGroupMessageEventPostReplyEvent : + OneBotNormalGroupMessageEventInteractionEvent, + OnebotGroupMessageEventPostReplyEvent { + override val content: OneBotNormalGroupMessageEvent +} + +// OneBotAnonymousGroupMessageEvent + +/** + * OneBot组件中针对 [OneBotAnonymousGroupMessageEvent] 的拦截或通知事件。 + * @since 1.6.0 + */ +public interface OneBotAnonymousGroupMessageEventInteractionEvent : + OneBotGroupMessageEventInteractionEvent, + ChatGroupMessageEventInteractionEvent { + override val content: OneBotAnonymousGroupMessageEvent +} + +/** + * OneBot组件中针对 [OneBotAnonymousGroupMessageEvent.reply] 的拦截事件。 + * + * @since 1.6.0 + */ +public interface OneBotAnonymousGroupMessageEventPreReplyEvent : + OneBotAnonymousGroupMessageEventInteractionEvent, + OnebotGroupMessageEventPreReplyEvent { + override val content: OneBotAnonymousGroupMessageEvent +} + +/** + * OneBot组件中针对 [OneBotAnonymousGroupMessageEvent.reply] 的通知事件。 + * @since 1.6.0 + */ +public interface OneBotAnonymousGroupMessageEventPostReplyEvent : + OneBotAnonymousGroupMessageEventInteractionEvent, + OnebotGroupMessageEventPostReplyEvent { + override val content: OneBotAnonymousGroupMessageEvent +} + +// OneBotNoticeGroupMessageEvent + +/** + * OneBot组件中针对 [OneBotNoticeGroupMessageEvent] 的拦截或通知事件。 + * @since 1.6.0 + */ +public interface OneBotNoticeGroupMessageEventInteractionEvent : + OneBotGroupMessageEventInteractionEvent { + override val content: OneBotNoticeGroupMessageEvent +} + +/** + * OneBot组件中针对 [OneBotNoticeGroupMessageEvent.reply] 的拦截事件。 + * + * @since 1.6.0 + */ +public interface OneBotNoticeGroupMessageEventPreReplyEvent : + OneBotNoticeGroupMessageEventInteractionEvent, + OnebotGroupMessageEventPreReplyEvent { + override val content: OneBotNoticeGroupMessageEvent +} + +/** + * OneBot组件中针对 [OneBotNoticeGroupMessageEvent.reply] 的通知事件。 + * @since 1.6.0 + */ +public interface OneBotNoticeGroupMessageEventPostReplyEvent : + OneBotNoticeGroupMessageEventInteractionEvent, + OnebotGroupMessageEventPostReplyEvent { + override val content: OneBotNoticeGroupMessageEvent +} + +//endregion diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupMessageEventInteractionTests.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupMessageEventInteractionTests.kt new file mode 100644 index 00000000..d035186b --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupMessageEventInteractionTests.kt @@ -0,0 +1,89 @@ +package love.forte.simbot.component.onebot.v11.core.event + +import io.mockk.coEvery +import io.mockk.coVerifyOrder +import io.mockk.mockk +import io.mockk.spyk +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.test.runTest +import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.overwriteWith +import love.forte.simbot.common.id.IntID.Companion.ID +import love.forte.simbot.component.onebot.common.annotations.ApiResultConstructor +import love.forte.simbot.component.onebot.v11.core.OneBot11 +import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotConfiguration +import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component +import love.forte.simbot.component.onebot.v11.core.event.internal.message.OneBotNormalGroupMessageEventImpl +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotNormalGroupMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotNormalGroupMessageEventPreReplyEvent +import love.forte.simbot.component.onebot.v11.core.useOneBot11 +import love.forte.simbot.core.application.launchSimpleApplication +import love.forte.simbot.event.EventDispatcher +import love.forte.simbot.event.InteractionMessage +import love.forte.simbot.event.process +import love.forte.simbot.event.throwIfError +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.test.Test + + +/** + * + * @author ForteScarlet + */ +class GroupMessageEventInteractionTests { + private fun spykBot(dispatcher: EventDispatcher): OneBotBotImpl { + return spyk( + OneBotBotImpl( + "1234", + EmptyCoroutineContext, + SupervisorJob(), + OneBotBotConfiguration(), + OneBot11Component(), + dispatcher, + Json(OneBot11.DefaultJson) { + serializersModule = serializersModule overwriteWith OneBot11.serializersModule + } + ), + recordPrivateCalls = true + ) + } + + @OptIn(ApiResultConstructor::class) + @Test + fun testNormalGroupInteractionEvent() = runTest { + val app = launchSimpleApplication { + useOneBot11() + } + + app.eventDispatcher.process { event -> + event.reply("Hello") + } + + app.eventDispatcher.process { event -> + event.currentMessage = InteractionMessage.valueOf("Hello, World") + } + + val bot = spykBot(app.eventDispatcher) + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + val event = spyk( + OneBotNormalGroupMessageEventImpl( + null, + mockk(relaxed = true), + bot + ), + recordPrivateCalls = true + ) + + app.eventDispatcher.push(event).throwIfError().collect() + + coVerifyOrder { + event.reply("Hello") + event invoke "replyText" withArguments listOf("Hello, World") + } + } + +} From c92394ceb622950d1b05ed6134190f9a5059cc20 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Fri, 28 Feb 2025 16:56:51 +0800 Subject: [PATCH 07/11] Try to fix Git 'Filename too long' in Windows --- ...ntImpls.kt => OneBotAnonymousGroupMsgInteractionEventImpls.kt} | 0 ...ventImpls.kt => OneBotDefaultGroupMsgInteractionEventImpls.kt} | 0 ...EventImpls.kt => OneBotNormalGroupMsgInteractionEventImpls.kt} | 0 ...EventImpls.kt => OneBotNoticeGroupMsgInteractionEventImpls.kt} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotAnonymousGroupMessageEventInteractionEventImpls.kt => OneBotAnonymousGroupMsgInteractionEventImpls.kt} (100%) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotDefaultGroupMessageEventInteractionEventImpls.kt => OneBotDefaultGroupMsgInteractionEventImpls.kt} (100%) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotNormalGroupMessageEventInteractionEventImpls.kt => OneBotNormalGroupMsgInteractionEventImpls.kt} (100%) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotNoticeGroupMessageEventInteractionEventImpls.kt => OneBotNoticeGroupMsgInteractionEventImpls.kt} (100%) diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotAnonymousGroupMsgInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotAnonymousGroupMsgInteractionEventImpls.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotDefaultGroupMessageEventInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotDefaultGroupMsgInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotDefaultGroupMessageEventInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotDefaultGroupMsgInteractionEventImpls.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNormalGroupMessageEventInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNormalGroupMsgInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNormalGroupMessageEventInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNormalGroupMsgInteractionEventImpls.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNoticeGroupMessageEventInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNoticeGroupMsgInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNoticeGroupMessageEventInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNoticeGroupMsgInteractionEventImpls.kt From 6fcccb0d52b7a19c287edc18c5bc2efff56fa38e Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Fri, 28 Feb 2025 16:59:13 +0800 Subject: [PATCH 08/11] Try to fix Git 'Filename too long' in Windows --- ...ionEventImpls.kt => AnonymousGroupMsgInteractionEventImpls.kt} | 0 ...ctionEventImpls.kt => DefaultGroupMsgInteractionEventImpls.kt} | 0 ...endInteractionEventImpls.kt => FriendInteractionEventImpls.kt} | 0 ...roupInteractionEventImpls.kt => GroupInteractionEventImpls.kt} | 0 ...berInteractionEventImpls.kt => MemberInteractionEventImpls.kt} | 0 ...actionEventImpls.kt => NormalGroupMsgInteractionEventImpls.kt} | 0 ...actionEventImpls.kt => NoticeGroupMsgInteractionEventImpls.kt} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotAnonymousGroupMsgInteractionEventImpls.kt => AnonymousGroupMsgInteractionEventImpls.kt} (100%) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotDefaultGroupMsgInteractionEventImpls.kt => DefaultGroupMsgInteractionEventImpls.kt} (100%) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotFriendInteractionEventImpls.kt => FriendInteractionEventImpls.kt} (100%) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotGroupInteractionEventImpls.kt => GroupInteractionEventImpls.kt} (100%) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotMemberInteractionEventImpls.kt => MemberInteractionEventImpls.kt} (100%) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotNormalGroupMsgInteractionEventImpls.kt => NormalGroupMsgInteractionEventImpls.kt} (100%) rename simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/{OneBotNoticeGroupMsgInteractionEventImpls.kt => NoticeGroupMsgInteractionEventImpls.kt} (100%) diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotAnonymousGroupMsgInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/AnonymousGroupMsgInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotAnonymousGroupMsgInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/AnonymousGroupMsgInteractionEventImpls.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotDefaultGroupMsgInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/DefaultGroupMsgInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotDefaultGroupMsgInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/DefaultGroupMsgInteractionEventImpls.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotFriendInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/FriendInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotFriendInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/FriendInteractionEventImpls.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotGroupInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/GroupInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotGroupInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/GroupInteractionEventImpls.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotMemberInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/MemberInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotMemberInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/MemberInteractionEventImpls.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNormalGroupMsgInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/NormalGroupMsgInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNormalGroupMsgInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/NormalGroupMsgInteractionEventImpls.kt diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNoticeGroupMsgInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/NoticeGroupMsgInteractionEventImpls.kt similarity index 100% rename from simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/OneBotNoticeGroupMsgInteractionEventImpls.kt rename to simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/NoticeGroupMsgInteractionEventImpls.kt From f69dc04bf57c99397be8cd533de8917a9e528978 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Fri, 28 Feb 2025 17:01:11 +0800 Subject: [PATCH 09/11] Git allows longpath --- .github/workflows/test-branch.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test-branch.yml b/.github/workflows/test-branch.yml index b51da32b..75320233 100644 --- a/.github/workflows/test-branch.yml +++ b/.github/workflows/test-branch.yml @@ -28,6 +28,10 @@ jobs: os: [ macos-latest, windows-latest, ubuntu-latest ] runs-on: ${{ matrix.os }} steps: + # https://github.com/actions/checkout/issues/242#issuecomment-627501270 + # fix `Filename too long` 👆 + - name: git configure long path + run: git config --global core.longpaths true - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: From 357d856c8972fba1432e928bd3f3c91e239ed42d Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Mon, 3 Mar 2025 16:54:08 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=B9=B6=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=20Interaction=20=E7=9B=B8=E5=85=B3=E7=9A=84=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onebot/common/annotations/Marks.kt | 2 + .../api/simbot-component-onebot-v11-core.api | 93 ++++++++--- .../actor/internal/AbstractSendSupport.kt | 113 +++++++++++++ .../core/actor/internal/OneBotFriendImpl.kt | 75 ++------- .../core/actor/internal/OneBotGroupImpl.kt | 75 ++------- .../core/actor/internal/OneBotMemberImpl.kt | 75 ++------- .../message/OneBotGroupMessageEventImpl.kt | 86 ++-------- .../message/OneBotPrivateMessageEventImpl.kt | 107 +++++++++---- .../AbstractReplySupportInteractionEvent.kt | 110 +++++++++++++ .../DefaultGroupMsgInteractionEventImpls.kt | 8 +- .../DefaultPrivateMsgInteractionEventImpls.kt | 39 +++++ .../FriendMsgInteractionEventImpls.kt | 39 +++++ .../PrivateMsgInteractionEventImpls.kt | 39 +++++ .../OneBotInternalMessageInteractionEvent.kt | 4 +- .../OneBotMessageEventInteractionEvent.kt | 150 ++++++++++++++++-- .../OneBotSegmentsInteractionMessage.kt | 2 +- .../OneBotSendSupportInteractionEvent.kt | 7 +- .../GroupMessageEventInteractionTests.kt | 96 +++++++++-- .../PrivateMessageEventInteractionTests.kt | 139 ++++++++++++++++ 19 files changed, 912 insertions(+), 347 deletions(-) create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/AbstractSendSupport.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/AbstractReplySupportInteractionEvent.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/DefaultPrivateMsgInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/FriendMsgInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/PrivateMsgInteractionEventImpls.kt create mode 100644 simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/PrivateMessageEventInteractionTests.kt diff --git a/simbot-component-onebot-common/src/commonMain/kotlin/love/forte/simbot/component/onebot/common/annotations/Marks.kt b/simbot-component-onebot-common/src/commonMain/kotlin/love/forte/simbot/component/onebot/common/annotations/Marks.kt index 431209f8..10b09d8e 100644 --- a/simbot-component-onebot-common/src/commonMain/kotlin/love/forte/simbot/component/onebot/common/annotations/Marks.kt +++ b/simbot-component-onebot-common/src/commonMain/kotlin/love/forte/simbot/component/onebot/common/annotations/Marks.kt @@ -27,3 +27,5 @@ package love.forte.simbot.component.onebot.common.annotations @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) @MustBeDocumented public annotation class OneBotInternalImplementationsOnly + +// TODO be SubclassOptInRequired ? diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api index 0f1796f1..89af3c84 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api @@ -2310,11 +2310,12 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotAnonymousGroupMessageEvent; } -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPostReplyEvent { +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventPostReplyEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotAnonymousGroupMessageEvent; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; } -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPreReplyEvent { +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotAnonymousGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventPreReplyEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotAnonymousGroupMessageEvent; } @@ -2322,8 +2323,22 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotFriend; } +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendMessageEventInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotFriendMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventPostReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotFriendMessageEvent; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventPreReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotFriendMessageEvent; +} + public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendPostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPostSendEvent, love/forte/simbot/event/ContactPostSendEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotFriend; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; } public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendPreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotFriendInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPreSendEvent, love/forte/simbot/event/ContactPreSendEvent { @@ -2341,8 +2356,18 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent; } +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventPostReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventPreReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent; +} + public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupPostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPostSendEvent, love/forte/simbot/event/ChatGroupPostSendEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotGroup; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; } public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupPreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPreSendEvent, love/forte/simbot/event/ChatGroupPreSendEvent { @@ -2352,10 +2377,24 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public abstract fun setCurrentMessage (Llove/forte/simbot/event/InteractionMessage;)V } +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupPrivateMessageEventInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupPrivateMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupPrivateMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupPrivateMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventPostReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupPrivateMessageEvent; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupPrivateMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupPrivateMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventPreReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupPrivateMessageEvent; +} + public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent : love/forte/simbot/event/InternalMessageInteractionEvent { } public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessagePostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent, love/forte/simbot/event/InternalMessagePostSendEvent { + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; } public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessagePreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent, love/forte/simbot/event/InternalMessagePreSendEvent { @@ -2367,6 +2406,7 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMemberPostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMemberInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPostSendEvent, love/forte/simbot/event/MemberPostSendEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotMember; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; } public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMemberPreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMemberInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPreSendEvent, love/forte/simbot/event/MemberPreSendEvent { @@ -2381,15 +2421,25 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent; } +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent, love/forte/simbot/event/MessageEventPostReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent, love/forte/simbot/event/MessageEventPreReplyEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent; +} + public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent, love/forte/simbot/event/ChatGroupMessageEventInteractionEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNormalGroupMessageEvent; } -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPostReplyEvent { +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventPostReplyEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventInteractionEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNormalGroupMessageEvent; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; } -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPreReplyEvent { +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventPreReplyEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNormalGroupMessageEventInteractionEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNormalGroupMessageEvent; } @@ -2397,14 +2447,28 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNoticeGroupMessageEvent; } -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPostReplyEvent { +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventPostReplyEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventInteractionEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNoticeGroupMessageEvent; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; } -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventInteractionEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPreReplyEvent { +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventPreReplyEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotNoticeGroupMessageEventInteractionEvent { public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotNoticeGroupMessageEvent; } +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventInteractionEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotPrivateMessageEvent; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventPostReplyEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotPrivateMessageEvent; + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; +} + +public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventPreReplyEvent, love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotPrivateMessageEventInteractionEvent { + public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotPrivateMessageEvent; +} + public final class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage : love/forte/simbot/event/InteractionMessage$Extension { public static final field Companion Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage$Companion; public synthetic fun (Llove/forte/simbot/event/InteractionMessage;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -2427,27 +2491,12 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even } public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent, love/forte/simbot/event/SendSupportPostSendEvent { + public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage; } public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportPreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent, love/forte/simbot/event/SendSupportPreSendEvent { } -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent, love/forte/simbot/event/MessageEventPostReplyEvent { - public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent; -} - -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotGroupMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotGroupMessageEventInteractionEvent, love/forte/simbot/event/MessageEventPreReplyEvent { - public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotGroupMessageEvent; -} - -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotMessageEventPostReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent, love/forte/simbot/event/MessageEventPostReplyEvent { - public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent; -} - -public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OnebotMessageEventPreReplyEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent, love/forte/simbot/event/MessageEventPreReplyEvent { - public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent; -} - public abstract interface class love/forte/simbot/component/onebot/v11/core/event/meta/OneBotHeartbeatEvent : love/forte/simbot/component/onebot/v11/core/event/meta/OneBotMetaEvent { public fun getIntervalMilliseconds ()J public abstract fun getSourceEvent ()Llove/forte/simbot/component/onebot/v11/event/meta/RawHeartbeatEvent; diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/AbstractSendSupport.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/AbstractSendSupport.kt new file mode 100644 index 00000000..3ed09d93 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/AbstractSendSupport.kt @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.actor.internal + +import love.forte.simbot.ability.SendSupport +import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult +import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.AbstractMessagePreSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotInternalMessagePostSendEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.segmentsOrNull +import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt +import love.forte.simbot.component.onebot.v11.core.utils.emitMessagePreSendEventAndUseCurrentMessage +import love.forte.simbot.component.onebot.v11.core.utils.resolveInteractionMessage +import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList +import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt +import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment +import love.forte.simbot.event.InteractionMessage +import love.forte.simbot.message.Message +import love.forte.simbot.message.MessageContent +import love.forte.simbot.message.PlainText + + +/** + * + * @author ForteScarlet + */ +internal abstract class AbstractSendSupport : SendSupport { + protected abstract val bot: OneBotBotImpl + + protected abstract fun preSendEvent( + interactionMessage: OneBotSegmentsInteractionMessage + ): AbstractMessagePreSendEventImpl + + protected abstract fun OneBotMessageReceipt.postSendEvent( + interactionMessage: InteractionMessage + ): OneBotInternalMessagePostSendEvent + + protected abstract suspend fun sendText(text: String): SendMsgResult + + protected abstract suspend fun sendSegments(segments: List): SendMsgResult + + protected suspend fun sendMessage(message: Message): SendMsgResult { + return when (message) { + is PlainText -> sendText(message.text) + else -> sendSegments(message.resolveToOneBotSegmentList(bot)) + } + } + + override suspend fun send(text: String): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(text = text) + return interceptionAndSend(interactionMessage) + } + + override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(content = messageContent) + return interceptionAndSend(interactionMessage) + } + + override suspend fun send(message: Message): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(message = message, bot = bot) + return interceptionAndSend(interactionMessage) + } + + protected suspend fun interceptionAndSend( + interactionMessage: OneBotSegmentsInteractionMessage + ): OneBotMessageReceipt { + val event = preSendEvent(interactionMessage) + + val currentMessage = bot.emitMessagePreSendEventAndUseCurrentMessage(event) + val segments = currentMessage.segmentsOrNull + if (segments != null) { + return sendSegments(segments).toReceipt(bot).alsoPostSend(currentMessage) + } + + return sendByInteractionMessage(currentMessage).toReceipt(bot).alsoPostSend(currentMessage) + } + + /** + * 解析一个 [InteractionMessage] 为一个 [OneBotMessageSegment] 的列表并发送。 + * 始终认为 `segments` 为 `null`。 + */ + protected suspend fun sendByInteractionMessage(interactionMessage: InteractionMessage): SendMsgResult { + return resolveInteractionMessage( + interactionMessage = interactionMessage, + onSegments = { sendSegments(it) }, + onMessage = { sendMessage(it) }, + onText = { sendText(it) }, + ) + } + + protected fun OneBotMessageReceipt.alsoPostSend( + interactionMessage: InteractionMessage + ): OneBotMessageReceipt = apply { + val event = postSendEvent(interactionMessage) + bot.pushEventAndLaunch(event) + } +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt index a3df9379..5bd54589 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt @@ -25,72 +25,32 @@ import love.forte.simbot.component.onebot.v11.core.api.GetStrangerInfoApi import love.forte.simbot.component.onebot.v11.core.api.SendLikeApi import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.AbstractMessagePreSendEventImpl import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotFriendPostSendEventImpl import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotFriendPreSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotInternalMessagePostSendEvent import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage -import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.segmentsOrNull import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage -import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt -import love.forte.simbot.component.onebot.v11.core.utils.* +import love.forte.simbot.component.onebot.v11.core.utils.sendPrivateMsgApi +import love.forte.simbot.component.onebot.v11.core.utils.sendPrivateTextMsgApi import love.forte.simbot.component.onebot.v11.event.message.RawPrivateMessageEvent import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment import love.forte.simbot.event.InteractionMessage -import love.forte.simbot.message.Message -import love.forte.simbot.message.MessageContent -import love.forte.simbot.message.PlainText import kotlin.coroutines.CoroutineContext -internal abstract class OneBotFriendImpl : OneBotFriend { - protected abstract val bot: OneBotBotImpl +internal abstract class OneBotFriendImpl : AbstractSendSupport(), OneBotFriend { + abstract override val bot: OneBotBotImpl - override suspend fun send(text: String): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(text = text) - return interceptionAndSend(interactionMessage) - } - - override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(content = messageContent) - return interceptionAndSend(interactionMessage) - } - - override suspend fun send(message: Message): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(message = message, bot = bot) - return interceptionAndSend(interactionMessage) - } - - private suspend fun interceptionAndSend( - interactionMessage: OneBotSegmentsInteractionMessage - ): OneBotMessageReceipt { - val event = OneBotFriendPreSendEventImpl( + override fun preSendEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl { + return OneBotFriendPreSendEventImpl( this, bot, interactionMessage ) - - val currentMessage = bot.emitMessagePreSendEventAndUseCurrentMessage(event) - val segments = currentMessage.segmentsOrNull - if (segments != null) { - return sendSegments(segments).toReceipt(bot).alsoPostSend(currentMessage) - } - - return sendByInteractionMessage(currentMessage).toReceipt(bot).alsoPostSend(currentMessage) - } - - /** - * 解析一个 [InteractionMessage] 为一个 [OneBotMessageSegment] 的列表并发送。 - * 始终认为 `segments` 为 `null`。 - */ - private suspend fun sendByInteractionMessage(interactionMessage: InteractionMessage): SendMsgResult { - return resolveInteractionMessage( - interactionMessage = interactionMessage, - onSegments = { sendSegments(it) }, - onMessage = { sendMessage(it) }, - onText = { sendText(it) }, - ) } - private suspend fun sendText(text: String): SendMsgResult { + override suspend fun sendText(text: String): SendMsgResult { return bot.executeData( sendPrivateTextMsgApi( target = id, @@ -99,14 +59,7 @@ internal abstract class OneBotFriendImpl : OneBotFriend { ) } - private suspend fun sendMessage(message: Message): SendMsgResult { - return when (message) { - is PlainText -> sendText(message.text) - else -> sendSegments(message.resolveToOneBotSegmentList(bot)) - } - } - - private suspend fun sendSegments(segments: List): SendMsgResult { + override suspend fun sendSegments(segments: List): SendMsgResult { return bot.executeData( sendPrivateMsgApi( target = id, @@ -115,17 +68,13 @@ internal abstract class OneBotFriendImpl : OneBotFriend { ) } - private fun OneBotMessageReceipt.alsoPostSend( - interactionMessage: InteractionMessage - ): OneBotMessageReceipt = apply { - val event = OneBotFriendPostSendEventImpl( + override fun OneBotMessageReceipt.postSendEvent(interactionMessage: InteractionMessage): OneBotInternalMessagePostSendEvent { + return OneBotFriendPostSendEventImpl( content = this@OneBotFriendImpl, bot = bot, receipt = this, message = interactionMessage.toOneBotSegmentsInteractionMessage() ) - - bot.pushEventAndLaunch(event) } override suspend fun sendLike(times: Int) { diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt index c58e3b0c..bbba0af1 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt @@ -27,23 +27,17 @@ import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroupDeleteOption import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember import love.forte.simbot.component.onebot.v11.core.api.* import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.AbstractMessagePreSendEventImpl import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotGroupPostSendEventImpl import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotGroupPreSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotInternalMessagePostSendEvent import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage -import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.segmentsOrNull import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage -import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt -import love.forte.simbot.component.onebot.v11.core.utils.emitMessagePreSendEventAndUseCurrentMessage -import love.forte.simbot.component.onebot.v11.core.utils.resolveInteractionMessage -import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList import love.forte.simbot.component.onebot.v11.core.utils.sendGroupMsgApi import love.forte.simbot.component.onebot.v11.core.utils.sendGroupTextMsgApi import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment import love.forte.simbot.event.InteractionMessage -import love.forte.simbot.message.Message -import love.forte.simbot.message.MessageContent -import love.forte.simbot.message.PlainText import kotlin.concurrent.Volatile import kotlin.coroutines.CoroutineContext import kotlin.jvm.JvmInline @@ -51,8 +45,8 @@ import kotlin.jvm.JvmInline internal abstract class OneBotGroupImpl( initialName: String -) : OneBotGroup { - protected abstract val bot: OneBotBotImpl +) : AbstractSendSupport(), OneBotGroup { + abstract override val bot: OneBotBotImpl @Volatile override var name: String = initialName @@ -85,7 +79,6 @@ internal abstract class OneBotGroupImpl( return result.dataOrThrow.toMember(bot) } - override suspend fun setAnonymous(enable: Boolean) { bot.executeData( SetGroupAnonymousApi.create( @@ -95,53 +88,16 @@ internal abstract class OneBotGroupImpl( ) } - override suspend fun send(text: String): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(text) - return interceptionAndSend(interactionMessage) - } - - override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(messageContent) - return interceptionAndSend(interactionMessage) - } - - override suspend fun send(message: Message): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(message = message, bot = bot) - return interceptionAndSend(interactionMessage) - } - - private suspend fun interceptionAndSend( - interactionMessage: OneBotSegmentsInteractionMessage - ): OneBotMessageReceipt { - val event = OneBotGroupPreSendEventImpl( + override fun preSendEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl { + return OneBotGroupPreSendEventImpl( this, bot, interactionMessage ) - - val currentMessage = bot.emitMessagePreSendEventAndUseCurrentMessage(event) - val segments = currentMessage.segmentsOrNull - if (segments != null) { - return sendSegments(segments).toReceipt(bot).alsoPostSend(currentMessage) - } - - return sendByInteractionMessage(currentMessage).toReceipt(bot).alsoPostSend(currentMessage) } - /** - * 解析一个 InteractionMessage 为一个 OneBotMessageSegment 的列表并发送。 - * 始终认为 `segments` 为 `null`。 - */ - private suspend fun sendByInteractionMessage(interactionMessage: InteractionMessage): SendMsgResult { - return resolveInteractionMessage( - interactionMessage = interactionMessage, - onSegments = { sendSegments(it) }, - onMessage = { sendMessage(it) }, - onText = { sendText(it) }, - ) - } - private suspend fun sendText(text: String): SendMsgResult { + override suspend fun sendText(text: String): SendMsgResult { return bot.executeData( sendGroupTextMsgApi( target = id, @@ -150,14 +106,7 @@ internal abstract class OneBotGroupImpl( ) } - private suspend fun sendMessage(message: Message): SendMsgResult { - return when (message) { - is PlainText -> sendText(message.text) - else -> sendSegments(message.resolveToOneBotSegmentList(bot)) - } - } - - private suspend fun sendSegments(segments: List): SendMsgResult { + override suspend fun sendSegments(segments: List): SendMsgResult { return bot.executeData( sendGroupMsgApi( target = id, @@ -166,17 +115,15 @@ internal abstract class OneBotGroupImpl( ) } - private fun OneBotMessageReceipt.alsoPostSend( + override fun OneBotMessageReceipt.postSendEvent( interactionMessage: InteractionMessage - ): OneBotMessageReceipt = apply { - val event = OneBotGroupPostSendEventImpl( + ): OneBotInternalMessagePostSendEvent { + return OneBotGroupPostSendEventImpl( content = this@OneBotGroupImpl, bot = bot, receipt = this, message = interactionMessage.toOneBotSegmentsInteractionMessage() ) - - bot.pushEventAndLaunch(event) } override suspend fun delete(vararg options: DeleteOption) { diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt index 4872d968..52b2dc37 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotMemberImpl.kt @@ -27,21 +27,19 @@ import love.forte.simbot.component.onebot.v11.core.actor.OneBotMemberRole import love.forte.simbot.component.onebot.v11.core.actor.OneBotStranger import love.forte.simbot.component.onebot.v11.core.api.* import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.AbstractMessagePreSendEventImpl import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotMemberPostSendEventImpl import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotMemberPreSendEventImpl +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotInternalMessagePostSendEvent import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage -import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.segmentsOrNull import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage -import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt -import love.forte.simbot.component.onebot.v11.core.utils.* +import love.forte.simbot.component.onebot.v11.core.utils.sendPrivateMsgApi +import love.forte.simbot.component.onebot.v11.core.utils.sendPrivateTextMsgApi import love.forte.simbot.component.onebot.v11.event.message.RawGroupMessageEvent import love.forte.simbot.component.onebot.v11.event.message.RawPrivateMessageEvent import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment import love.forte.simbot.event.InteractionMessage -import love.forte.simbot.message.Message -import love.forte.simbot.message.MessageContent -import love.forte.simbot.message.PlainText import kotlin.concurrent.Volatile import kotlin.coroutines.CoroutineContext import kotlin.jvm.JvmInline @@ -51,8 +49,8 @@ import kotlin.time.Duration internal abstract class OneBotMemberImpl( initialRole: OneBotMemberRole?, initialNick: String? -) : OneBotMember { - protected abstract val bot: OneBotBotImpl +) : AbstractSendSupport(), OneBotMember { + abstract override val bot: OneBotBotImpl protected abstract val groupId: ID? protected inline val groupIdOrFailure: ID @@ -65,53 +63,15 @@ internal abstract class OneBotMemberImpl( @Volatile override var nick: String? = initialNick - override suspend fun send(text: String): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(text = text) - return interceptionAndSend(interactionMessage) - } - - override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(content = messageContent) - return interceptionAndSend(interactionMessage) - } - - override suspend fun send(message: Message): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(message = message, bot = bot) - return interceptionAndSend(interactionMessage) - } - - private suspend fun interceptionAndSend( - interactionMessage: OneBotSegmentsInteractionMessage - ): OneBotMessageReceipt { - val event = OneBotMemberPreSendEventImpl( + override fun preSendEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl { + return OneBotMemberPreSendEventImpl( this, bot, interactionMessage ) - - val currentMessage = bot.emitMessagePreSendEventAndUseCurrentMessage(event) - val segments = currentMessage.segmentsOrNull - if (segments != null) { - return sendSegments(segments).toReceipt(bot).alsoPostSend(currentMessage) - } - - return sendByInteractionMessage(currentMessage).toReceipt(bot).alsoPostSend(currentMessage) - } - - /** - * 解析一个 [InteractionMessage] 为一个 [OneBotMessageSegment] 的列表并发送。 - * 始终认为 `segments` 为 `null`。 - */ - private suspend fun sendByInteractionMessage(interactionMessage: InteractionMessage): SendMsgResult { - return resolveInteractionMessage( - interactionMessage = interactionMessage, - onSegments = { sendSegments(it) }, - onMessage = { sendMessage(it) }, - onText = { sendText(it) }, - ) } - private suspend fun sendText(text: String): SendMsgResult { + override suspend fun sendText(text: String): SendMsgResult { return bot.executeData( sendPrivateTextMsgApi( target = id, @@ -120,14 +80,7 @@ internal abstract class OneBotMemberImpl( ) } - private suspend fun sendMessage(message: Message): SendMsgResult { - return when (message) { - is PlainText -> sendText(message.text) - else -> sendSegments(message.resolveToOneBotSegmentList(bot)) - } - } - - private suspend fun sendSegments(segments: List): SendMsgResult { + override suspend fun sendSegments(segments: List): SendMsgResult { return bot.executeData( sendPrivateMsgApi( target = id, @@ -136,17 +89,15 @@ internal abstract class OneBotMemberImpl( ) } - private fun OneBotMessageReceipt.alsoPostSend( + override fun OneBotMessageReceipt.postSendEvent( interactionMessage: InteractionMessage - ): OneBotMessageReceipt = apply { - val event = OneBotMemberPostSendEventImpl( + ): OneBotInternalMessagePostSendEvent { + return OneBotMemberPostSendEventImpl( content = this@OneBotMemberImpl, bot = bot, receipt = this, message = interactionMessage.toOneBotSegmentsInteractionMessage() ) - - bot.pushEventAndLaunch(event) } override suspend fun delete(vararg options: DeleteOption) { diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt index abacba25..c649c358 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotGroupMessageEventImpl.kt @@ -31,25 +31,21 @@ import love.forte.simbot.component.onebot.v11.core.event.message.OneBotGroupMess import love.forte.simbot.component.onebot.v11.core.event.message.OneBotNormalGroupMessageEvent import love.forte.simbot.component.onebot.v11.core.event.message.OneBotNoticeGroupMessageEvent import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage -import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OnebotGroupMessageEventPostReplyEvent -import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.segmentsOrNull +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupMessageEventPostReplyEvent import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage import love.forte.simbot.component.onebot.v11.core.internal.message.OneBotMessageContentImpl -import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt -import love.forte.simbot.component.onebot.v11.core.utils.* +import love.forte.simbot.component.onebot.v11.core.utils.sendGroupMsgApi +import love.forte.simbot.component.onebot.v11.core.utils.sendGroupTextMsgApi import love.forte.simbot.component.onebot.v11.event.message.RawGroupMessageEvent import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment import love.forte.simbot.event.InteractionMessage -import love.forte.simbot.message.Message -import love.forte.simbot.message.MessageContent -import love.forte.simbot.message.PlainText internal abstract class OneBotGroupMessageEventImpl( sourceEvent: RawGroupMessageEvent, final override val bot: OneBotBotImpl -) : OneBotGroupMessageEvent { +) : AbstractReplySupportInteractionEvent(), OneBotGroupMessageEvent { override val id: ID get() = "${sourceEvent.groupId}-${sourceEvent.messageId}".ID @@ -68,52 +64,13 @@ internal abstract class OneBotGroupMessageEventImpl( ?: error("Group with id $groupId is not found") } - override suspend fun reply(text: String): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(text = text) - return interceptionAndReply(interactionMessage) - } - - override suspend fun reply(messageContent: MessageContent): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(content = messageContent) - return interceptionAndReply(interactionMessage) - } - - override suspend fun reply(message: Message): OneBotMessageReceipt { - val interactionMessage = OneBotSegmentsInteractionMessage(message = message, bot = bot) - return interceptionAndReply(interactionMessage) - } - - protected abstract fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): + abstract override fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl - private suspend fun interceptionAndReply( - interactionMessage: OneBotSegmentsInteractionMessage - ): OneBotMessageReceipt { - val event = preReplyEvent(interactionMessage) - - val currentMessage = bot.emitMessagePreSendEventAndUseCurrentMessage(event) - val segments = currentMessage.segmentsOrNull - if (segments != null) { - return replySegments(segments).toReceipt(bot).alsoPostReply(currentMessage) - } - - return replyByInteractionMessage(currentMessage).toReceipt(bot).alsoPostReply(currentMessage) - } + abstract override fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): + OneBotGroupMessageEventPostReplyEvent - /** - * 解析一个 [InteractionMessage] 为一个 [OneBotMessageSegment] 的列表并发送。 - * 始终认为 `segments` 为 `null`。 - */ - private suspend fun replyByInteractionMessage(interactionMessage: InteractionMessage): SendMsgResult { - return resolveInteractionMessage( - interactionMessage = interactionMessage, - onSegments = { replySegments(it) }, - onMessage = { replyMessage(it) }, - onText = { replyText(it) }, - ) - } - - private suspend fun replyText(text: String): SendMsgResult { + override suspend fun replyText(text: String): SendMsgResult { return bot.executeData( sendGroupTextMsgApi( target = sourceEvent.groupId, @@ -123,14 +80,7 @@ internal abstract class OneBotGroupMessageEventImpl( ) } - private suspend fun replyMessage(message: Message): SendMsgResult { - return when (message) { - is PlainText -> replyText(message.text) - else -> replySegments(message.resolveToOneBotSegmentList(bot)) - } - } - - private suspend fun replySegments(segments: List): SendMsgResult { + override suspend fun replySegments(segments: List): SendMsgResult { return bot.executeData( sendGroupMsgApi( target = sourceEvent.groupId, @@ -139,16 +89,6 @@ internal abstract class OneBotGroupMessageEventImpl( ) ) } - - protected abstract fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): - OnebotGroupMessageEventPostReplyEvent - - private fun OneBotMessageReceipt.alsoPostReply( - interactionMessage: InteractionMessage - ): OneBotMessageReceipt = apply { - val event = postReplyEvent(interactionMessage) - bot.pushEventAndLaunch(event) - } } internal class OneBotNormalGroupMessageEventImpl( @@ -170,7 +110,7 @@ internal class OneBotNormalGroupMessageEventImpl( } override fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): - OnebotGroupMessageEventPostReplyEvent { + OneBotGroupMessageEventPostReplyEvent { return OneBotNormalGroupMessageEventPostReplyEventImpl( bot, content = this@OneBotNormalGroupMessageEventImpl, @@ -202,7 +142,7 @@ internal class OneBotAnonymousGroupMessageEventImpl( } override fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): - OnebotGroupMessageEventPostReplyEvent { + OneBotGroupMessageEventPostReplyEvent { return OneBotAnonymousGroupMessageEventPostReplyEventImpl( bot, content = this@OneBotAnonymousGroupMessageEventImpl, @@ -229,7 +169,7 @@ internal class OneBotNoticeGroupMessageEventImpl( } override fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): - OnebotGroupMessageEventPostReplyEvent { + OneBotGroupMessageEventPostReplyEvent { return OneBotNoticeGroupMessageEventPostReplyEventImpl( bot, content = this@OneBotNoticeGroupMessageEventImpl, @@ -256,7 +196,7 @@ internal class OneBotDefaultGroupMessageEventImpl( } override fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): - OnebotGroupMessageEventPostReplyEvent { + OneBotGroupMessageEventPostReplyEvent { return OneBotDefaultGroupMessageEventPostReplyEventImpl( bot, content = this@OneBotDefaultGroupMessageEventImpl, diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotPrivateMessageEventImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotPrivateMessageEventImpl.kt index 046a2773..98807beb 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotPrivateMessageEventImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/message/OneBotPrivateMessageEventImpl.kt @@ -24,27 +24,30 @@ import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroup import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember import love.forte.simbot.component.onebot.v11.core.actor.internal.toFriend import love.forte.simbot.component.onebot.v11.core.actor.internal.toMember +import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl import love.forte.simbot.component.onebot.v11.core.event.internal.eventToString +import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.* import love.forte.simbot.component.onebot.v11.core.event.message.OneBotFriendMessageEvent import love.forte.simbot.component.onebot.v11.core.event.message.OneBotGroupPrivateMessageEvent import love.forte.simbot.component.onebot.v11.core.event.message.OneBotPrivateMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotPrivateMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage import love.forte.simbot.component.onebot.v11.core.internal.message.OneBotMessageContentImpl -import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt -import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList import love.forte.simbot.component.onebot.v11.core.utils.sendPrivateMsgApi import love.forte.simbot.component.onebot.v11.core.utils.sendPrivateTextMsgApi import love.forte.simbot.component.onebot.v11.event.message.RawPrivateMessageEvent import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt -import love.forte.simbot.message.Message -import love.forte.simbot.message.MessageContent +import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment +import love.forte.simbot.event.InteractionMessage internal abstract class OneBotPrivateMessageEventImpl( final override val sourceEvent: RawPrivateMessageEvent, final override val bot: OneBotBotImpl, -) : OneBotPrivateMessageEvent { +) : AbstractReplySupportInteractionEvent(), OneBotPrivateMessageEvent { override val id: ID get() = "${sourceEvent.userId}-${sourceEvent.messageId}".ID @@ -57,36 +60,29 @@ internal abstract class OneBotPrivateMessageEventImpl( bot ) - override suspend fun reply(text: String): OneBotMessageReceipt { - val api = sendPrivateTextMsgApi( - target = sourceEvent.userId, - text, + override suspend fun replyText(text: String): SendMsgResult { + return bot.executeData( + sendPrivateTextMsgApi( + target = sourceEvent.userId, + text, + ) ) - - return bot.executeData(api).toReceipt(bot) } - override suspend fun reply(messageContent: MessageContent): OneBotMessageReceipt { - if (messageContent is OneBotMessageContent) { - return bot.executeData( - sendPrivateMsgApi( - target = sourceEvent.userId, - message = messageContent.sourceSegments, - ) - ).toReceipt(bot) - } - - return reply(messageContent.messages) - } - - override suspend fun reply(message: Message): OneBotMessageReceipt { + override suspend fun replySegments(segments: List): SendMsgResult { return bot.executeData( sendPrivateMsgApi( target = sourceEvent.userId, - message = message.resolveToOneBotSegmentList(bot) + message = segments ) - ).toReceipt(bot) + ) } + + abstract override fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): + AbstractMessagePreSendEventImpl + + abstract override fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): + OneBotPrivateMessageEventPostReplyEvent } internal class OneBotFriendMessageEventImpl( @@ -99,6 +95,25 @@ internal class OneBotFriendMessageEventImpl( return sourceEvent.sender.toFriend(bot) } + override fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl { + return OneBotFriendMessageEventPreReplyEventImpl( + bot, + this, + interactionMessage + ) + } + + override fun OneBotMessageReceipt.postReplyEvent( + interactionMessage: InteractionMessage + ): OneBotPrivateMessageEventPostReplyEvent { + return OneBotFriendMessageEventPostReplyEventImpl( + bot, + content = this@OneBotFriendMessageEventImpl, + receipt = this, + message = interactionMessage.toOneBotSegmentsInteractionMessage() + ) + } + override fun toString(): String = eventToString("OneBotFriendMessageEvent") } @@ -118,6 +133,25 @@ internal class OneBotGroupPrivateMessageEventImpl( throw UnsupportedOperationException("The way to get the group id from PrivateMessageEvent is unknown yet.") } + override fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl { + return OneBotGroupPrivateMessageEventPreReplyEventImpl( + bot, + this, + interactionMessage + ) + } + + override fun OneBotMessageReceipt.postReplyEvent( + interactionMessage: InteractionMessage + ): OneBotPrivateMessageEventPostReplyEvent { + return OneBotGroupPrivateMessageEventPostReplyEventImpl( + bot, + content = this@OneBotGroupPrivateMessageEventImpl, + receipt = this, + message = interactionMessage.toOneBotSegmentsInteractionMessage() + ) + } + override fun toString(): String = eventToString("OneBotGroupPrivateMessageEvent") } @@ -128,6 +162,25 @@ internal class OneBotDefaultPrivateMessageEventImpl( bot: OneBotBotImpl, ) : OneBotPrivateMessageEventImpl(sourceEvent, bot) { + override fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): AbstractMessagePreSendEventImpl { + return OneBotDefaultPrivateMessageEventPreReplyEventImpl( + bot, + this, + interactionMessage + ) + } + + override fun OneBotMessageReceipt.postReplyEvent( + interactionMessage: InteractionMessage + ): OneBotPrivateMessageEventPostReplyEvent { + return OneBotDefaultPrivateMessageEventPostReplyEventImpl( + bot, + content = this@OneBotDefaultPrivateMessageEventImpl, + receipt = this, + message = interactionMessage.toOneBotSegmentsInteractionMessage() + ) + } + override fun toString(): String = eventToString("OneBotDefaultPrivateMessageEvent") } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/AbstractReplySupportInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/AbstractReplySupportInteractionEvent.kt new file mode 100644 index 00000000..72589769 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/AbstractReplySupportInteractionEvent.kt @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.ability.ReplySupport +import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult +import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.segmentsOrNull +import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt +import love.forte.simbot.component.onebot.v11.core.utils.emitMessagePreSendEventAndUseCurrentMessage +import love.forte.simbot.component.onebot.v11.core.utils.resolveInteractionMessage +import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList +import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt +import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment +import love.forte.simbot.event.InteractionMessage +import love.forte.simbot.message.Message +import love.forte.simbot.message.MessageContent +import love.forte.simbot.message.PlainText + + +/** + * + * @author ForteScarlet + */ +internal abstract class AbstractReplySupportInteractionEvent : ReplySupport { + protected abstract val bot: OneBotBotImpl + + protected abstract fun preReplyEvent(interactionMessage: OneBotSegmentsInteractionMessage): + AbstractMessagePreSendEventImpl + + protected abstract fun OneBotMessageReceipt.postReplyEvent(interactionMessage: InteractionMessage): + OneBotMessageEventPostReplyEvent + + override suspend fun reply(text: String): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(text = text) + return interceptionAndReply(interactionMessage) + } + + override suspend fun reply(messageContent: MessageContent): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(content = messageContent) + return interceptionAndReply(interactionMessage) + } + + override suspend fun reply(message: Message): OneBotMessageReceipt { + val interactionMessage = OneBotSegmentsInteractionMessage(message = message, bot = bot) + return interceptionAndReply(interactionMessage) + } + + protected abstract suspend fun replyText(text: String): SendMsgResult + + protected abstract suspend fun replySegments(segments: List): SendMsgResult + + protected suspend fun replyMessage(message: Message): SendMsgResult { + return when (message) { + is PlainText -> replyText(message.text) + else -> replySegments(message.resolveToOneBotSegmentList(bot)) + } + } + + protected suspend fun interceptionAndReply( + interactionMessage: OneBotSegmentsInteractionMessage + ): OneBotMessageReceipt { + val event = preReplyEvent(interactionMessage) + + val currentMessage = bot.emitMessagePreSendEventAndUseCurrentMessage(event) + val segments = currentMessage.segmentsOrNull + if (segments != null) { + return replySegments(segments).toReceipt(bot).alsoPostReply(currentMessage) + } + + return replyByInteractionMessage(currentMessage).toReceipt(bot).alsoPostReply(currentMessage) + } + + /** + * 解析一个 [InteractionMessage] 为一个 [OneBotMessageSegment] 的列表并发送。 + * 始终认为 `segments` 为 `null`。 + */ + protected suspend fun replyByInteractionMessage(interactionMessage: InteractionMessage): SendMsgResult { + return resolveInteractionMessage( + interactionMessage = interactionMessage, + onSegments = { replySegments(it) }, + onMessage = { replyMessage(it) }, + onText = { replyText(it) }, + ) + } + + protected fun OneBotMessageReceipt.alsoPostReply( + interactionMessage: InteractionMessage + ): OneBotMessageReceipt = apply { + val event = postReplyEvent(interactionMessage) + bot.pushEventAndLaunch(event) + } +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/DefaultGroupMsgInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/DefaultGroupMsgInteractionEventImpls.kt index 9de51b83..7a956e0f 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/DefaultGroupMsgInteractionEventImpls.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/DefaultGroupMsgInteractionEventImpls.kt @@ -20,19 +20,19 @@ package love.forte.simbot.component.onebot.v11.core.event.internal.messageintera import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot import love.forte.simbot.component.onebot.v11.core.event.internal.message.OneBotDefaultGroupMessageEventImpl import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage -import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OnebotGroupMessageEventPostReplyEvent -import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OnebotGroupMessageEventPreReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupMessageEventPreReplyEvent import love.forte.simbot.message.MessageReceipt internal class OneBotDefaultGroupMessageEventPreReplyEventImpl( override val bot: OneBotBot, override val content: OneBotDefaultGroupMessageEventImpl, message: OneBotSegmentsInteractionMessage, -) : AbstractMessagePreSendEventImpl(message), OnebotGroupMessageEventPreReplyEvent +) : AbstractMessagePreSendEventImpl(message), OneBotGroupMessageEventPreReplyEvent internal class OneBotDefaultGroupMessageEventPostReplyEventImpl( override val bot: OneBotBot, override val content: OneBotDefaultGroupMessageEventImpl, override val receipt: MessageReceipt, override val message: OneBotSegmentsInteractionMessage, -) : AbstractMessagePostSendEventImpl(), OnebotGroupMessageEventPostReplyEvent +) : AbstractMessagePostSendEventImpl(), OneBotGroupMessageEventPostReplyEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/DefaultPrivateMsgInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/DefaultPrivateMsgInteractionEventImpls.kt new file mode 100644 index 00000000..264ecf8c --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/DefaultPrivateMsgInteractionEventImpls.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotPrivateMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotPrivateMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotPrivateMessageEventPreReplyEvent +import love.forte.simbot.message.MessageReceipt + + +internal class OneBotDefaultPrivateMessageEventPreReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotPrivateMessageEvent, + message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePreSendEventImpl(message), OneBotPrivateMessageEventPreReplyEvent + +internal class OneBotDefaultPrivateMessageEventPostReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotPrivateMessageEvent, + override val receipt: MessageReceipt, + override val message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePostSendEventImpl(), OneBotPrivateMessageEventPostReplyEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/FriendMsgInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/FriendMsgInteractionEventImpls.kt new file mode 100644 index 00000000..e8e62e6a --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/FriendMsgInteractionEventImpls.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotFriendMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotFriendMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotFriendMessageEventPreReplyEvent +import love.forte.simbot.message.MessageReceipt + + +internal class OneBotFriendMessageEventPreReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotFriendMessageEvent, + message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePreSendEventImpl(message), OneBotFriendMessageEventPreReplyEvent + +internal class OneBotFriendMessageEventPostReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotFriendMessageEvent, + override val receipt: MessageReceipt, + override val message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePostSendEventImpl(), OneBotFriendMessageEventPostReplyEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/PrivateMsgInteractionEventImpls.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/PrivateMsgInteractionEventImpls.kt new file mode 100644 index 00000000..637d13cc --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/messageinteraction/PrivateMsgInteractionEventImpls.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025. ForteScarlet. + * + * This file is part of simbot-component-onebot. + * + * simbot-component-onebot is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-onebot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-onebot. + * If not, see . + */ + +package love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction + +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotGroupPrivateMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupPrivateMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupPrivateMessageEventPreReplyEvent +import love.forte.simbot.message.MessageReceipt + + +internal class OneBotGroupPrivateMessageEventPreReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotGroupPrivateMessageEvent, + message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePreSendEventImpl(message), OneBotGroupPrivateMessageEventPreReplyEvent + +internal class OneBotGroupPrivateMessageEventPostReplyEventImpl( + override val bot: OneBotBot, + override val content: OneBotGroupPrivateMessageEvent, + override val receipt: MessageReceipt, + override val message: OneBotSegmentsInteractionMessage, +) : AbstractMessagePostSendEventImpl(), OneBotGroupPrivateMessageEventPostReplyEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt index 452c954d..b4acf9cd 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent.kt @@ -55,4 +55,6 @@ public interface OneBotInternalMessagePreSendEvent : @SubclassOptInRequired(FuzzyEventTypeImplementation::class) public interface OneBotInternalMessagePostSendEvent : OneBotInternalMessageInteractionEvent, - InternalMessagePostSendEvent + InternalMessagePostSendEvent { + override val message: OneBotSegmentsInteractionMessage +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt index cc99387f..d1c545a8 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotMessageEventInteractionEvent.kt @@ -46,7 +46,7 @@ public interface OneBotMessageEventInteractionEvent : * @since 1.6.0 */ @OptIn(FuzzyEventTypeImplementation::class) -public interface OnebotMessageEventPreReplyEvent : OneBotMessageEventInteractionEvent, MessageEventPreReplyEvent { +public interface OneBotMessageEventPreReplyEvent : OneBotMessageEventInteractionEvent, MessageEventPreReplyEvent { override val content: OneBotMessageEvent } @@ -56,8 +56,9 @@ public interface OnebotMessageEventPreReplyEvent : OneBotMessageEventInteraction * @since 1.6.0 */ @OptIn(FuzzyEventTypeImplementation::class) -public interface OnebotMessageEventPostReplyEvent : OneBotMessageEventInteractionEvent, MessageEventPostReplyEvent { +public interface OneBotMessageEventPostReplyEvent : OneBotMessageEventInteractionEvent, MessageEventPostReplyEvent { override val content: OneBotMessageEvent + override val message: OneBotSegmentsInteractionMessage } //region Group @@ -81,9 +82,9 @@ public interface OneBotGroupMessageEventInteractionEvent : * @since 1.6.0 */ @OptIn(FuzzyEventTypeImplementation::class) -public interface OnebotGroupMessageEventPreReplyEvent : +public interface OneBotGroupMessageEventPreReplyEvent : OneBotGroupMessageEventInteractionEvent, - MessageEventPreReplyEvent { + OneBotMessageEventPreReplyEvent { override val content: OneBotGroupMessageEvent } @@ -93,10 +94,11 @@ public interface OnebotGroupMessageEventPreReplyEvent : * @since 1.6.0 */ @OptIn(FuzzyEventTypeImplementation::class) -public interface OnebotGroupMessageEventPostReplyEvent : +public interface OneBotGroupMessageEventPostReplyEvent : OneBotGroupMessageEventInteractionEvent, - MessageEventPostReplyEvent { + OneBotMessageEventPostReplyEvent { override val content: OneBotGroupMessageEvent + override val message: OneBotSegmentsInteractionMessage } // OneBotNormalGroupMessageEvent @@ -118,7 +120,7 @@ public interface OneBotNormalGroupMessageEventInteractionEvent : */ public interface OneBotNormalGroupMessageEventPreReplyEvent : OneBotNormalGroupMessageEventInteractionEvent, - OnebotGroupMessageEventPreReplyEvent { + OneBotGroupMessageEventPreReplyEvent { override val content: OneBotNormalGroupMessageEvent } @@ -128,8 +130,9 @@ public interface OneBotNormalGroupMessageEventPreReplyEvent : */ public interface OneBotNormalGroupMessageEventPostReplyEvent : OneBotNormalGroupMessageEventInteractionEvent, - OnebotGroupMessageEventPostReplyEvent { + OneBotGroupMessageEventPostReplyEvent { override val content: OneBotNormalGroupMessageEvent + override val message: OneBotSegmentsInteractionMessage } // OneBotAnonymousGroupMessageEvent @@ -151,7 +154,7 @@ public interface OneBotAnonymousGroupMessageEventInteractionEvent : */ public interface OneBotAnonymousGroupMessageEventPreReplyEvent : OneBotAnonymousGroupMessageEventInteractionEvent, - OnebotGroupMessageEventPreReplyEvent { + OneBotGroupMessageEventPreReplyEvent { override val content: OneBotAnonymousGroupMessageEvent } @@ -161,8 +164,9 @@ public interface OneBotAnonymousGroupMessageEventPreReplyEvent : */ public interface OneBotAnonymousGroupMessageEventPostReplyEvent : OneBotAnonymousGroupMessageEventInteractionEvent, - OnebotGroupMessageEventPostReplyEvent { + OneBotGroupMessageEventPostReplyEvent { override val content: OneBotAnonymousGroupMessageEvent + override val message: OneBotSegmentsInteractionMessage } // OneBotNoticeGroupMessageEvent @@ -183,7 +187,7 @@ public interface OneBotNoticeGroupMessageEventInteractionEvent : */ public interface OneBotNoticeGroupMessageEventPreReplyEvent : OneBotNoticeGroupMessageEventInteractionEvent, - OnebotGroupMessageEventPreReplyEvent { + OneBotGroupMessageEventPreReplyEvent { override val content: OneBotNoticeGroupMessageEvent } @@ -193,8 +197,130 @@ public interface OneBotNoticeGroupMessageEventPreReplyEvent : */ public interface OneBotNoticeGroupMessageEventPostReplyEvent : OneBotNoticeGroupMessageEventInteractionEvent, - OnebotGroupMessageEventPostReplyEvent { + OneBotGroupMessageEventPostReplyEvent { override val content: OneBotNoticeGroupMessageEvent + override val message: OneBotSegmentsInteractionMessage } //endregion + +// Privates + +//region Private + +/** + * OneBot组件中针对 [OneBotPrivateMessageEvent] 的拦截或通知事件。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotPrivateMessageEventInteractionEvent : + OneBotMessageEventInteractionEvent { + override val content: OneBotPrivateMessageEvent +} + +/** + * OneBot组件中针对 [OneBotPrivateMessageEvent.reply] 的拦截事件。 + * 可以对其中的参数进行修改。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotPrivateMessageEventPreReplyEvent : + OneBotPrivateMessageEventInteractionEvent, + OneBotMessageEventPreReplyEvent { + override val content: OneBotPrivateMessageEvent +} + +/** + * OneBot组件中针对 [OneBotPrivateMessageEvent.reply] 的通知事件。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotPrivateMessageEventPostReplyEvent : + OneBotPrivateMessageEventInteractionEvent, + OneBotMessageEventPostReplyEvent { + override val content: OneBotPrivateMessageEvent + override val message: OneBotSegmentsInteractionMessage +} +//region Group Private + +/** + * OneBot组件中针对 [OneBotPrivateMessageEvent] 的拦截或通知事件。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotGroupPrivateMessageEventInteractionEvent : + OneBotPrivateMessageEventInteractionEvent { + override val content: OneBotGroupPrivateMessageEvent +} + +/** + * OneBot组件中针对 [OneBotPrivateMessageEvent.reply] 的拦截事件。 + * 可以对其中的参数进行修改。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotGroupPrivateMessageEventPreReplyEvent : + OneBotGroupPrivateMessageEventInteractionEvent, + OneBotPrivateMessageEventPreReplyEvent { + override val content: OneBotGroupPrivateMessageEvent +} + +/** + * OneBot组件中针对 [OneBotPrivateMessageEvent.reply] 的通知事件。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotGroupPrivateMessageEventPostReplyEvent : + OneBotGroupPrivateMessageEventInteractionEvent, + OneBotPrivateMessageEventPostReplyEvent { + override val content: OneBotGroupPrivateMessageEvent + override val message: OneBotSegmentsInteractionMessage +} +//endregion + +//region Friend Private + +/** + * OneBot组件中针对 [OneBotFriendMessageEvent] 的拦截或通知事件。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotFriendMessageEventInteractionEvent : + OneBotPrivateMessageEventInteractionEvent { + override val content: OneBotFriendMessageEvent +} + +/** + * OneBot组件中针对 [OneBotFriendMessageEvent.reply] 的拦截事件。 + * 可以对其中的参数进行修改。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotFriendMessageEventPreReplyEvent : + OneBotFriendMessageEventInteractionEvent, + OneBotPrivateMessageEventPreReplyEvent { + override val content: OneBotFriendMessageEvent +} + +/** + * OneBot组件中针对 [OneBotFriendMessageEvent.reply] 的通知事件。 + * + * @since 1.6.0 + */ +@OptIn(FuzzyEventTypeImplementation::class) +public interface OneBotFriendMessageEventPostReplyEvent : + OneBotFriendMessageEventInteractionEvent, + OneBotPrivateMessageEventPostReplyEvent { + override val content: OneBotFriendMessageEvent + override val message: OneBotSegmentsInteractionMessage +} +//endregion +//endregion diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt index 8ee4f843..3a9c0735 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage.kt @@ -51,7 +51,7 @@ public class OneBotSegmentsInteractionMessage private constructor( * * ## 接收时 * - * 当通过事件获取到 [OneBotSegmentsInteractionMessage] 时: + * 当通过 post send/reply 事件获取到 [OneBotSegmentsInteractionMessage] 时: * - 如果 [message] 为 [InteractionMessage.Text] 时, * 代表发送纯文本消息,不需要解析 `segments`, 此时 [segments] 为 `null`。 * diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt index 1db122cc..a315b0d0 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSendSupportInteractionEvent.kt @@ -62,7 +62,9 @@ public interface OneBotSendSupportPreSendEvent : SendSupportPreSendEvent, OneBot * @author ForteScarlet */ @SubclassOptInRequired(FuzzyEventTypeImplementation::class) -public interface OneBotSendSupportPostSendEvent : SendSupportPostSendEvent, OneBotSendSupportInteractionEvent +public interface OneBotSendSupportPostSendEvent : SendSupportPostSendEvent, OneBotSendSupportInteractionEvent { + override val message: OneBotSegmentsInteractionMessage +} //region OneBotGroup @@ -112,6 +114,7 @@ public interface OneBotGroupPostSendEvent : OneBotGroupInteractionEvent, ChatGroupPostSendEvent { override val content: OneBotGroup + override val message: OneBotSegmentsInteractionMessage } //endregion @@ -163,6 +166,7 @@ public interface OneBotFriendPostSendEvent : OneBotFriendInteractionEvent, ContactPostSendEvent { override val content: OneBotFriend + override val message: OneBotSegmentsInteractionMessage } //endregion @@ -201,5 +205,6 @@ public interface OneBotMemberPostSendEvent : OneBotMemberInteractionEvent, MemberPostSendEvent { override val content: OneBotMember + override val message: OneBotSegmentsInteractionMessage } //endregion diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupMessageEventInteractionTests.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupMessageEventInteractionTests.kt index d035186b..c0de6936 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupMessageEventInteractionTests.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/GroupMessageEventInteractionTests.kt @@ -4,11 +4,13 @@ import io.mockk.coEvery import io.mockk.coVerifyOrder import io.mockk.mockk import io.mockk.spyk +import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.flow.collect import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json import kotlinx.serialization.modules.overwriteWith +import love.forte.simbot.ability.ReplySupport import love.forte.simbot.common.id.IntID.Companion.ID import love.forte.simbot.component.onebot.common.annotations.ApiResultConstructor import love.forte.simbot.component.onebot.v11.core.OneBot11 @@ -16,17 +18,21 @@ import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotConfiguration import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component +import love.forte.simbot.component.onebot.v11.core.event.internal.message.OneBotAnonymousGroupMessageEventImpl import love.forte.simbot.component.onebot.v11.core.event.internal.message.OneBotNormalGroupMessageEventImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.message.OneBotNoticeGroupMessageEventImpl +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotAnonymousGroupMessageEvent import love.forte.simbot.component.onebot.v11.core.event.message.OneBotNormalGroupMessageEvent -import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotNormalGroupMessageEventPreReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotNoticeGroupMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.* import love.forte.simbot.component.onebot.v11.core.useOneBot11 import love.forte.simbot.core.application.launchSimpleApplication -import love.forte.simbot.event.EventDispatcher -import love.forte.simbot.event.InteractionMessage -import love.forte.simbot.event.process -import love.forte.simbot.event.throwIfError +import love.forte.simbot.event.* import kotlin.coroutines.EmptyCoroutineContext import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertIs +import kotlin.test.assertNull /** @@ -51,32 +57,82 @@ class GroupMessageEventInteractionTests { ) } - @OptIn(ApiResultConstructor::class) @Test fun testNormalGroupInteractionEvent() = runTest { + testInteractionTextReplacementEvent< + OneBotNormalGroupMessageEvent, + OneBotNormalGroupMessageEventPreReplyEvent, + OneBotNormalGroupMessageEventPostReplyEvent, + > { bot -> + OneBotNormalGroupMessageEventImpl( + null, + mockk(relaxed = true), + bot + ) + } + } + + @Test + fun testAnonymousGroupMessageEvent() = runTest { + testInteractionTextReplacementEvent< + OneBotAnonymousGroupMessageEvent, + OneBotAnonymousGroupMessageEventPreReplyEvent, + OneBotAnonymousGroupMessageEventPostReplyEvent, + > { bot -> + OneBotAnonymousGroupMessageEventImpl( + null, + mockk(relaxed = true), + bot + ) + } + } + + @Test + fun testNoticeGroupMessageEvent() = runTest { + testInteractionTextReplacementEvent< + OneBotNoticeGroupMessageEvent, + OneBotNoticeGroupMessageEventPreReplyEvent, + OneBotNoticeGroupMessageEventPostReplyEvent, + > { bot -> + OneBotNoticeGroupMessageEventImpl( + null, + mockk(relaxed = true), + bot + ) + } + } + + + @OptIn(ApiResultConstructor::class) + private suspend inline fun < + reified E, + reified PRE_E : OneBotGroupMessageEventPreReplyEvent, + reified POST_E : OneBotGroupMessageEventPostReplyEvent + > testInteractionTextReplacementEvent( + block: (b: OneBotBotImpl) -> E, + ) where E : Event, E : ReplySupport { val app = launchSimpleApplication { useOneBot11() } - app.eventDispatcher.process { event -> + app.eventDispatcher.process { event -> event.reply("Hello") } - app.eventDispatcher.process { event -> + app.eventDispatcher.process { event -> event.currentMessage = InteractionMessage.valueOf("Hello, World") } + val postEventDeferred = CompletableDeferred() + + app.eventDispatcher.process { event -> + postEventDeferred.complete(event) + } + val bot = spykBot(app.eventDispatcher) coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) - val event = spyk( - OneBotNormalGroupMessageEventImpl( - null, - mockk(relaxed = true), - bot - ), - recordPrivateCalls = true - ) + val event = spyk(block(bot), recordPrivateCalls = true) app.eventDispatcher.push(event).throwIfError().collect() @@ -84,6 +140,12 @@ class GroupMessageEventInteractionTests { event.reply("Hello") event invoke "replyText" withArguments listOf("Hello, World") } - } + val postEvent = postEventDeferred.await() + val postEventMessage = postEvent.message + assertIs(postEventMessage) + assertIs(postEventMessage.message) + assertNull(postEventMessage.segments) + assertEquals("Hello, World", postEventMessage.message.text) + } } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/PrivateMessageEventInteractionTests.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/PrivateMessageEventInteractionTests.kt new file mode 100644 index 00000000..6175611f --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/jvmTest/kotlin/love/forte/simbot/component/onebot/v11/core/event/PrivateMessageEventInteractionTests.kt @@ -0,0 +1,139 @@ +package love.forte.simbot.component.onebot.v11.core.event + +import io.mockk.coEvery +import io.mockk.coVerifyOrder +import io.mockk.mockk +import io.mockk.spyk +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.test.runTest +import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.overwriteWith +import love.forte.simbot.ability.ReplySupport +import love.forte.simbot.common.id.IntID.Companion.ID +import love.forte.simbot.component.onebot.common.annotations.ApiResultConstructor +import love.forte.simbot.component.onebot.v11.core.OneBot11 +import love.forte.simbot.component.onebot.v11.core.api.SendMsgResult +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotConfiguration +import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl +import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component +import love.forte.simbot.component.onebot.v11.core.event.internal.message.OneBotFriendMessageEventImpl +import love.forte.simbot.component.onebot.v11.core.event.internal.message.OneBotGroupPrivateMessageEventImpl +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotFriendMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.message.OneBotGroupPrivateMessageEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotFriendMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotFriendMessageEventPreReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupPrivateMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotGroupPrivateMessageEventPreReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotPrivateMessageEventPostReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotPrivateMessageEventPreReplyEvent +import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage +import love.forte.simbot.component.onebot.v11.core.useOneBot11 +import love.forte.simbot.core.application.launchSimpleApplication +import love.forte.simbot.event.* +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertIs +import kotlin.test.assertNull + + +/** + * + * @author ForteScarlet + */ +class PrivateMessageEventInteractionTests { + private fun spykBot(dispatcher: EventDispatcher): OneBotBotImpl { + return spyk( + OneBotBotImpl( + "1234", + EmptyCoroutineContext, + SupervisorJob(), + OneBotBotConfiguration(), + OneBot11Component(), + dispatcher, + Json(OneBot11.DefaultJson) { + serializersModule = serializersModule overwriteWith OneBot11.serializersModule + } + ), + recordPrivateCalls = true + ) + } + + @Test + fun testFriendMessageEvent() = runTest { + testInteractionEvent< + OneBotFriendMessageEvent, + OneBotFriendMessageEventPreReplyEvent, + OneBotFriendMessageEventPostReplyEvent, + > { bot -> + OneBotFriendMessageEventImpl( + null, + mockk(relaxed = true), + bot + ) + } + } + + @Test + fun testGroupPrivateMessageEvent() = runTest { + testInteractionEvent< + OneBotGroupPrivateMessageEvent, + OneBotGroupPrivateMessageEventPreReplyEvent, + OneBotGroupPrivateMessageEventPostReplyEvent, + > { bot -> + OneBotGroupPrivateMessageEventImpl( + null, + mockk(relaxed = true), + bot + ) + } + } + + @OptIn(ApiResultConstructor::class) + private suspend inline fun < + reified E, + reified PRE_E : OneBotPrivateMessageEventPreReplyEvent, + reified POST_E : OneBotPrivateMessageEventPostReplyEvent + > testInteractionEvent( + block: (b: OneBotBotImpl) -> E, + ) where E : Event, E : ReplySupport { + val app = launchSimpleApplication { + useOneBot11() + } + + app.eventDispatcher.process { event -> + event.reply("Hello") + } + + app.eventDispatcher.process { event -> + event.currentMessage = InteractionMessage.valueOf("Hello, World") + } + + val postEventDeferred = CompletableDeferred() + + app.eventDispatcher.process { event -> + postEventDeferred.complete(event) + } + + val bot = spykBot(app.eventDispatcher) + coEvery { bot.executeData(any()) } returns SendMsgResult(114.ID) + + val event = spyk(block(bot), recordPrivateCalls = true) + + app.eventDispatcher.push(event).throwIfError().collect() + + coVerifyOrder { + event.reply("Hello") + event invoke "replyText" withArguments listOf("Hello, World") + } + + val postEvent = postEventDeferred.await() + val postEventMessage = postEvent.message + assertIs(postEventMessage) + assertIs(postEventMessage.message) + assertNull(postEventMessage.segments) + assertEquals("Hello, World", postEventMessage.message.text) + } +} From 70de708a803c20589928893d46d31d584da6a9e0 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Mon, 3 Mar 2025 16:59:51 +0800 Subject: [PATCH 11/11] Detekt fix --- .../onebot/v11/core/actor/internal/OneBotFriendImpl.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt index 5bd54589..1ca2d314 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotFriendImpl.kt @@ -68,7 +68,9 @@ internal abstract class OneBotFriendImpl : AbstractSendSupport(), OneBotFriend { ) } - override fun OneBotMessageReceipt.postSendEvent(interactionMessage: InteractionMessage): OneBotInternalMessagePostSendEvent { + override fun OneBotMessageReceipt.postSendEvent( + interactionMessage: InteractionMessage + ): OneBotInternalMessagePostSendEvent { return OneBotFriendPostSendEventImpl( content = this@OneBotFriendImpl, bot = bot,