Skip to content

Commit b738d7b

Browse files
committed
feat: 实现 OneBotGroup.send 的拦截事件和成功回调事件
1 parent a9fff4c commit b738d7b

File tree

15 files changed

+768
-31
lines changed

15 files changed

+768
-31
lines changed

simbot-component-onebot-common/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ kotlin {
5151
sourceSets {
5252
commonMain.dependencies {
5353
implementation(libs.simbot.api)
54-
implementation(libs.simbot.common.annotations)
54+
api(libs.simbot.common.annotations)
5555
}
5656

5757
commonTest.dependencies {
@@ -61,6 +61,7 @@ kotlin {
6161

6262
jvmMain {
6363
dependencies {
64+
compileOnly(libs.simbot.api)
6465
}
6566
}
6667

simbot-component-onebot-v11/simbot-component-onebot-v11-core/api/simbot-component-onebot-v11-core.api

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,6 +2140,16 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even
21402140
public fun getTime ()Llove/forte/simbot/common/time/Timestamp;
21412141
}
21422142

2143+
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 {
2144+
}
2145+
2146+
public class love/forte/simbot/component/onebot/v11/core/event/OneBotInternalInterceptionException : love/forte/simbot/event/InternalInterceptionException {
2147+
public fun <init> ()V
2148+
public fun <init> (Ljava/lang/String;)V
2149+
public fun <init> (Ljava/lang/String;Ljava/lang/Throwable;)V
2150+
public fun <init> (Ljava/lang/Throwable;)V
2151+
}
2152+
21432153
public final class love/forte/simbot/component/onebot/v11/core/event/OneBotUnknownEvent : love/forte/simbot/component/onebot/v11/core/event/OneBotEvent {
21442154
public fun <init> (Ljava/lang/String;Llove/forte/simbot/component/onebot/v11/event/UnknownEvent;)V
21452155
public final fun component1 ()Ljava/lang/String;
@@ -2296,6 +2306,57 @@ public abstract interface class love/forte/simbot/component/onebot/v11/core/even
22962306
public fun getSubType ()Ljava/lang/String;
22972307
}
22982308

2309+
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 {
2310+
public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotGroup;
2311+
}
2312+
2313+
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 {
2314+
public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotGroup;
2315+
}
2316+
2317+
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 {
2318+
public abstract fun getContent ()Llove/forte/simbot/component/onebot/v11/core/actor/OneBotGroup;
2319+
public abstract fun getCurrentMessage ()Llove/forte/simbot/event/InteractionMessage;
2320+
public abstract fun getMessage ()Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage;
2321+
public abstract fun setCurrentMessage (Llove/forte/simbot/event/InteractionMessage;)V
2322+
}
2323+
2324+
public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent : love/forte/simbot/event/InternalMessageInteractionEvent {
2325+
}
2326+
2327+
public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessagePostSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent {
2328+
}
2329+
2330+
public abstract interface class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessagePreSendEvent : love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotInternalMessageInteractionEvent {
2331+
}
2332+
2333+
public final class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage : love/forte/simbot/event/InteractionMessage$Extension {
2334+
public static final field Companion Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage$Companion;
2335+
public synthetic fun <init> (Llove/forte/simbot/event/InteractionMessage;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
2336+
public static final fun create (Llove/forte/simbot/event/InteractionMessage;Ljava/util/List;)Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage;
2337+
public fun equals (Ljava/lang/Object;)Z
2338+
public final fun getMessage ()Llove/forte/simbot/event/InteractionMessage;
2339+
public final fun getSegments ()Ljava/util/List;
2340+
public fun hashCode ()I
2341+
public fun toString ()Ljava/lang/String;
2342+
}
2343+
2344+
public final class love/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage$Companion {
2345+
public final fun create (Llove/forte/simbot/event/InteractionMessage;Ljava/util/List;)Llove/forte/simbot/component/onebot/v11/core/event/messageinteraction/OneBotSegmentsInteractionMessage;
2346+
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;
2347+
}
2348+
2349+
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 {
2350+
public abstract fun getBot ()Llove/forte/simbot/component/onebot/v11/core/bot/OneBotBot;
2351+
public abstract fun getContent ()Llove/forte/simbot/ability/SendSupport;
2352+
}
2353+
2354+
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 {
2355+
}
2356+
2357+
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 {
2358+
}
2359+
22992360
public abstract interface class love/forte/simbot/component/onebot/v11/core/event/meta/OneBotHeartbeatEvent : love/forte/simbot/component/onebot/v11/core/event/meta/OneBotMetaEvent {
23002361
public fun getIntervalMilliseconds ()J
23012362
public abstract fun getSourceEvent ()Llove/forte/simbot/component/onebot/v11/event/meta/RawHeartbeatEvent;

simbot-component-onebot-v11/simbot-component-onebot-v11-core/build.gradle.kts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,12 @@ kotlin {
6060

6161
sourceSets {
6262
commonMain.dependencies {
63+
// JVM compileOnly
6364
implementation(libs.simbot.api)
64-
implementation(libs.simbot.common.annotations)
65+
implementation(libs.jetbrains.annotations)
66+
67+
api(libs.simbot.common.annotations)
68+
implementation(libs.simbot.common.atomic)
6569

6670
api(project(":simbot-component-onebot-common"))
6771
api(project(":simbot-component-onebot-v11:simbot-component-onebot-v11-common"))
@@ -88,7 +92,9 @@ kotlin {
8892

8993
jvmMain {
9094
dependencies {
95+
compileOnly(libs.simbot.api)
9196
compileOnly(libs.ktor.client.contentNegotiation)
97+
compileOnly(libs.jetbrains.annotations)
9298
}
9399
}
94100

simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/actor/internal/OneBotGroupImpl.kt

Lines changed: 127 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,21 @@ import love.forte.simbot.component.onebot.v11.core.actor.OneBotGroupDeleteOption
2727
import love.forte.simbot.component.onebot.v11.core.actor.OneBotMember
2828
import love.forte.simbot.component.onebot.v11.core.api.*
2929
import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotImpl
30+
import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotGroupPostSendEventImpl
31+
import love.forte.simbot.component.onebot.v11.core.event.internal.messageinteraction.OneBotGroupPreSendEventImpl
32+
import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.OneBotSegmentsInteractionMessage
33+
import love.forte.simbot.component.onebot.v11.core.event.messageinteraction.toOneBotSegmentsInteractionMessage
3034
import love.forte.simbot.component.onebot.v11.core.internal.message.toReceipt
3135
import love.forte.simbot.component.onebot.v11.core.utils.resolveToOneBotSegmentList
3236
import love.forte.simbot.component.onebot.v11.core.utils.sendGroupMsgApi
3337
import love.forte.simbot.component.onebot.v11.core.utils.sendGroupTextMsgApi
3438
import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent
3539
import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt
40+
import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment
41+
import love.forte.simbot.event.InteractionMessage
3642
import love.forte.simbot.message.Message
3743
import love.forte.simbot.message.MessageContent
44+
import love.forte.simbot.message.PlainText
3845
import kotlin.concurrent.Volatile
3946
import kotlin.coroutines.CoroutineContext
4047
import kotlin.jvm.JvmInline
@@ -87,34 +94,123 @@ internal abstract class OneBotGroupImpl(
8794
}
8895

8996
override suspend fun send(text: String): OneBotMessageReceipt {
97+
val interactionMessage = OneBotSegmentsInteractionMessage.create(
98+
message = InteractionMessage.valueOf(text),
99+
segments = null
100+
)
101+
102+
return interceptionAndSend(interactionMessage)
103+
}
104+
105+
override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt {
106+
val interactionMessage = OneBotSegmentsInteractionMessage.create(
107+
message = InteractionMessage.valueOf(messageContent),
108+
segments = (messageContent as? OneBotMessageContent)?.sourceSegments
109+
)
110+
111+
return interceptionAndSend(interactionMessage)
112+
}
113+
114+
override suspend fun send(message: Message): OneBotMessageReceipt {
115+
val interactionMessage = OneBotSegmentsInteractionMessage.create(
116+
message = InteractionMessage.valueOf(message),
117+
segments = message.resolveToOneBotSegmentList(bot)
118+
)
119+
120+
return interceptionAndSend(interactionMessage)
121+
}
122+
123+
private suspend fun interceptionAndSend(
124+
interactionMessage: OneBotSegmentsInteractionMessage
125+
): OneBotMessageReceipt {
126+
val event = OneBotGroupPreSendEventImpl(
127+
this,
128+
bot,
129+
interactionMessage
130+
)
131+
132+
bot.emitMessagePreSendEvent(event)
133+
val currentMessage = event.useCurrentMessage()
134+
val segments = (currentMessage as? OneBotSegmentsInteractionMessage)?.segments
135+
if (segments != null) {
136+
return sendSegments(segments).toReceipt(bot).alsoPostSend(currentMessage)
137+
}
138+
139+
return sendByInteractionMessage(currentMessage).toReceipt(bot).alsoPostSend(currentMessage)
140+
}
141+
142+
/**
143+
* 解析一个 InteractionMessage 为一个 OneBotMessageSegment 的列表并发送。
144+
* 始终认为 `segments` 为 `null`。
145+
*/
146+
private suspend fun sendByInteractionMessage(
147+
interactionMessage: InteractionMessage,
148+
allowSegmentMessage: Boolean = true
149+
): SendMsgResult {
150+
return when (interactionMessage) {
151+
is InteractionMessage.Message -> sendMessage(interactionMessage.message)
152+
is InteractionMessage.MessageContent -> {
153+
val messageContent = interactionMessage.messageContent
154+
if (messageContent is OneBotMessageContent) {
155+
sendSegments(messageContent.sourceSegments)
156+
} else {
157+
sendMessage(messageContent.messages)
158+
}
159+
}
160+
161+
is InteractionMessage.Text -> sendText(interactionMessage.text)
162+
is OneBotSegmentsInteractionMessage -> {
163+
if (!allowSegmentMessage) {
164+
error(
165+
"InteractionMessage.message does not support the type OneBotSegmentsInteractionMessage, " +
166+
"but $interactionMessage"
167+
)
168+
}
169+
170+
sendByInteractionMessage(interactionMessage.message, false)
171+
}
172+
173+
else -> error("Unknown InteractionMessage type: $interactionMessage")
174+
}
175+
}
176+
177+
178+
private suspend fun sendText(text: String): SendMsgResult {
90179
return bot.executeData(
91180
sendGroupTextMsgApi(
92181
target = id,
93182
text = text,
94183
)
95-
).toReceipt(bot)
184+
)
96185
}
97186

98-
override suspend fun send(messageContent: MessageContent): OneBotMessageReceipt {
99-
if (messageContent is OneBotMessageContent) {
100-
return bot.executeData(
101-
sendGroupMsgApi(
102-
target = id,
103-
message = messageContent.sourceSegments,
104-
)
105-
).toReceipt(bot)
187+
private suspend fun sendMessage(message: Message): SendMsgResult {
188+
return when (message) {
189+
is PlainText -> sendText(message.text)
190+
else -> sendSegments(message.resolveToOneBotSegmentList(bot))
106191
}
107-
108-
return send(messageContent.messages)
109192
}
110193

111-
override suspend fun send(message: Message): OneBotMessageReceipt {
194+
private suspend fun sendSegments(segments: List<OneBotMessageSegment>): SendMsgResult {
112195
return bot.executeData(
113196
sendGroupMsgApi(
114197
target = id,
115-
message = message.resolveToOneBotSegmentList(bot)
198+
message = segments,
116199
)
117-
).toReceipt(bot)
200+
)
201+
}
202+
203+
private fun OneBotMessageReceipt.alsoPostSend(
204+
interactionMessage: InteractionMessage
205+
): OneBotMessageReceipt = apply {
206+
val event = OneBotGroupPostSendEventImpl(
207+
content = this@OneBotGroupImpl,
208+
bot = bot,
209+
receipt = this,
210+
message = interactionMessage.toOneBotSegmentsInteractionMessage()
211+
)
212+
213+
bot.pushEventAndLaunch(event)
118214
}
119215

120216
override suspend fun delete(vararg options: DeleteOption) {
@@ -206,6 +302,23 @@ internal abstract class OneBotGroupImpl(
206302
bot.executeData(GetGroupHonorInfoApi.create(groupId = id, type = type))
207303

208304
override fun toString(): String = "OneBotGroup(id=$id, bot=${bot.id})"
305+
override fun equals(other: Any?): Boolean {
306+
if (this === other) return true
307+
if (other !is OneBotGroupImpl) return false
308+
309+
if (name != other.name) return false
310+
if (bot != other.bot) return false
311+
312+
return true
313+
}
314+
315+
override fun hashCode(): Int {
316+
var result = name.hashCode()
317+
result = 31 * result + bot.hashCode()
318+
return result
319+
}
320+
321+
209322
}
210323

211324
/**

simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotImpl.kt

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ import io.ktor.client.statement.*
2424
import io.ktor.http.*
2525
import io.ktor.websocket.*
2626
import kotlinx.coroutines.*
27-
import kotlinx.coroutines.flow.Flow
28-
import kotlinx.coroutines.flow.collect
29-
import kotlinx.coroutines.flow.launchIn
27+
import kotlinx.coroutines.flow.*
3028
import kotlinx.coroutines.sync.Mutex
3129
import kotlinx.coroutines.sync.withLock
3230
import kotlinx.serialization.SerializationException
@@ -54,8 +52,12 @@ import love.forte.simbot.component.onebot.v11.core.actor.internal.toGroup
5452
import love.forte.simbot.component.onebot.v11.core.actor.internal.toMember
5553
import love.forte.simbot.component.onebot.v11.core.actor.internal.toStranger
5654
import love.forte.simbot.component.onebot.v11.core.api.*
57-
import love.forte.simbot.component.onebot.v11.core.bot.*
55+
import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot
56+
import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotConfiguration
57+
import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotFriendRelation
58+
import love.forte.simbot.component.onebot.v11.core.bot.OneBotBotGroupRelation
5859
import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component
60+
import love.forte.simbot.component.onebot.v11.core.event.OneBotInternalInterceptionException
5961
import love.forte.simbot.component.onebot.v11.core.event.OneBotUnknownEvent
6062
import love.forte.simbot.component.onebot.v11.core.event.OneBotUnsupportedEvent
6163
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
7880
import love.forte.simbot.component.onebot.v11.event.resolveEventSerializer
7981
import love.forte.simbot.component.onebot.v11.event.resolveEventSubTypeFieldName
8082
import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent
81-
import love.forte.simbot.event.Event
82-
import love.forte.simbot.event.EventProcessor
83-
import love.forte.simbot.event.EventResult
83+
import love.forte.simbot.event.*
8484
import love.forte.simbot.logger.LoggerFactory
8585
import kotlin.concurrent.Volatile
8686
import kotlin.coroutines.CoroutineContext
@@ -299,7 +299,6 @@ internal class OneBotBotImpl(
299299
return WsEventSession(wsClient, host)
300300
}
301301

302-
303302
private inner class WsEventSession(
304303
val wsClient: HttpClient,
305304
val wsHost: Url
@@ -643,12 +642,30 @@ internal class OneBotBotImpl(
643642
return pushEvent(resolveRawEventToEvent(rawEvent, event))
644643
}
645644

646-
private fun pushEvent(event: Event): Flow<EventResult> {
645+
internal fun pushEvent(event: Event): Flow<EventResult> {
647646
return eventProcessor
648647
.push(event)
649648
.onEachErrorLog(logger)
650649
}
651650

651+
internal fun pushEventAndLaunch(event: Event): Job {
652+
return pushEvent(event).launchIn(this)
653+
}
654+
655+
internal suspend fun emitMessagePreSendEvent(event: InternalMessagePreSendEvent) {
656+
val errors = eventProcessor
657+
.push(event)
658+
.filterIsInstance<StandardEventResult.Error>()
659+
.toList()
660+
661+
if (errors.isNotEmpty()) {
662+
val ex = OneBotInternalInterceptionException("Internal message pre send event process failed")
663+
errors.forEach { ex.addSuppressed(it.content) }
664+
logger.error("Internal message pre send event process failed", ex)
665+
throw ex
666+
}
667+
}
668+
652669
override fun toString(): String =
653670
"OneBotBot(uniqueId='$uniqueId', isStarted=$isStarted, isActive=$isActive)"
654671
}

0 commit comments

Comments
 (0)