diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/OneBotBotManager.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/OneBotBotManager.kt index e7a1d3d..fc13dd4 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/OneBotBotManager.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/OneBotBotManager.kt @@ -34,6 +34,7 @@ import love.forte.simbot.component.NoSuchComponentException import love.forte.simbot.component.find import love.forte.simbot.component.onebot.v11.core.bot.internal.OneBotBotManagerImpl import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component +import love.forte.simbot.logger.LoggerFactory import love.forte.simbot.plugin.PluginConfigureContext import love.forte.simbot.plugin.PluginFactory import love.forte.simbot.plugin.PluginFactoryConfigurerProvider @@ -86,6 +87,10 @@ public abstract class OneBotBotManager : BotManager, JobBasedBotManager() { } } + internal val logger = LoggerFactory.getLogger( + "love.forte.simbot.component.onebot.v11.core.bot.OneBotBotManager" + ) + override val key: PluginFactory.Key = object : PluginFactory.Key {} override fun create( 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 c0349df..0ad2b0b 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 @@ -37,6 +37,7 @@ import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.cancel import kotlinx.coroutines.delay import kotlinx.coroutines.ensureActive +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.isActive import kotlinx.coroutines.launch @@ -81,6 +82,8 @@ import love.forte.simbot.component.onebot.v11.core.event.internal.message.OneBot import love.forte.simbot.component.onebot.v11.core.event.internal.message.OneBotGroupPrivateMessageEventImpl 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.internal.stage.OneBotBotStartedEventImpl +import love.forte.simbot.component.onebot.v11.core.utils.onEachErrorLog import love.forte.simbot.component.onebot.v11.event.UnknownEvent import love.forte.simbot.component.onebot.v11.event.message.GroupMessageEvent import love.forte.simbot.component.onebot.v11.event.message.PrivateMessageEvent @@ -88,7 +91,6 @@ import love.forte.simbot.component.onebot.v11.event.resolveEventSerializer import love.forte.simbot.component.onebot.v11.event.resolveEventSubTypeFieldName import love.forte.simbot.event.Event import love.forte.simbot.event.EventProcessor -import love.forte.simbot.event.onEachError import love.forte.simbot.logger.LoggerFactory import kotlin.concurrent.Volatile import kotlin.coroutines.CoroutineContext @@ -248,7 +250,7 @@ internal class OneBotBotImpl( private val startLock = Mutex() - override suspend fun start() = startLock.withLock { + override suspend fun start(): Unit = startLock.withLock { job.ensureActive() wsSession = createEventSession().also { s -> @@ -256,6 +258,12 @@ internal class OneBotBotImpl( } isStarted = true + launch { + eventProcessor + .push(OneBotBotStartedEventImpl(this@OneBotBotImpl)) + .onEachErrorLog(logger) + .collect() + } } private fun createEventSession(): WsEventSession { @@ -528,13 +536,7 @@ internal class OneBotBotImpl( private fun pushEvent(event: Event): Job { return eventProcessor .push(event) - .onEachError { errRes -> - logger.error( - "Event process with an error result: {}", - errRes.content.message, - errRes.content - ) - } + .onEachErrorLog(logger) .launchIn(this@OneBotBotImpl) } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotManagerImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotManagerImpl.kt index 9b10a20..c0749c2 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotManagerImpl.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/bot/internal/OneBotBotManagerImpl.kt @@ -17,7 +17,10 @@ package love.forte.simbot.component.onebot.v11.core.bot.internal +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch import love.forte.simbot.bot.BotRegisterFailureException import love.forte.simbot.bot.NoSuchBotException import love.forte.simbot.common.collection.computeValue @@ -26,10 +29,12 @@ import love.forte.simbot.common.collection.removeValue import love.forte.simbot.common.coroutines.mergeWith import love.forte.simbot.common.id.ID import love.forte.simbot.common.id.literal -import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component 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.OneBotBotManager +import love.forte.simbot.component.onebot.v11.core.component.OneBot11Component +import love.forte.simbot.component.onebot.v11.core.event.internal.stage.OneBotBotRegisteredEventImpl +import love.forte.simbot.component.onebot.v11.core.utils.onEachErrorLog import love.forte.simbot.event.EventProcessor import kotlin.coroutines.CoroutineContext @@ -40,10 +45,11 @@ import kotlin.coroutines.CoroutineContext */ internal class OneBotBotManagerImpl( override val job: Job, - private val coroutineContext: CoroutineContext, + override val coroutineContext: CoroutineContext, private val component: OneBot11Component, private val eventProcessor: EventProcessor -) : OneBotBotManager() { +) : OneBotBotManager(), CoroutineScope { + private val bots = concurrentMutableMap() override fun all(): Sequence = @@ -82,6 +88,15 @@ internal class OneBotBotManagerImpl( bots.removeValue(uniqueId) { created } } + // push event + launch { + eventProcessor + .push(OneBotBotRegisteredEventImpl(created)) + .onEachErrorLog(logger) + .collect() + } + + return created } @@ -90,4 +105,6 @@ internal class OneBotBotManagerImpl( override fun find(id: ID): OneBotBot? = bots[id.literal] + + } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/OneBotEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/OneBotEvent.kt index 93d0596..2925bb5 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/OneBotEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/OneBotEvent.kt @@ -19,7 +19,10 @@ package love.forte.simbot.component.onebot.v11.core.event import love.forte.simbot.common.id.LongID import love.forte.simbot.common.time.Timestamp +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.stage.OneBotBotStageEvent import love.forte.simbot.component.onebot.v11.core.utils.timestamp +import love.forte.simbot.event.BotEvent import love.forte.simbot.event.Event /** @@ -27,12 +30,21 @@ import love.forte.simbot.event.Event */ public typealias OBSourceEvent = love.forte.simbot.component.onebot.v11.event.Event +/** + * 一个OneBot组件事件基类。 + * 是 [OneBotEvent] 的父类, + * 也是一些与OneBot协议本身无关的事件类型 + * (例如 [OneBotBotStageEvent]) 的父类。 + */ +public interface OneBotCommonEvent : Event + + /** * OneBot11的[事件](https://github.com/botuniverse/onebot-11/tree/master/event)。 * * @author ForteScarlet */ -public interface OneBotEvent : Event { +public interface OneBotEvent : OneBotCommonEvent { /** * 来自事件JSON的反序列化数据体。 */ @@ -62,3 +74,10 @@ public interface OneBotEvent : Event { public val postType: String get() = sourceEvent.postType } + +/** + * OneBot组件事件中的 [BotEvent]。 + */ +public interface OneBotBotEvent : OneBotEvent, BotEvent { + override val bot: OneBotBot +} diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/stage/OneBotBotStageEventImpl.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/stage/OneBotBotStageEventImpl.kt new file mode 100644 index 0000000..b13e8ed --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/internal/stage/OneBotBotStageEventImpl.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024. 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.stage + +import love.forte.simbot.annotations.ExperimentalSimbotAPI +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.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.stage.OneBotBotRegisteredEvent +import love.forte.simbot.component.onebot.v11.core.event.stage.OneBotBotStartedEvent + +internal class OneBotBotRegisteredEventImpl( + override val bot: OneBotBot +) : OneBotBotRegisteredEvent { + override val id: ID = UUID.random() + + @OptIn(ExperimentalSimbotAPI::class) + override val time: Timestamp = Timestamp.now() +} + +internal class OneBotBotStartedEventImpl( + override val bot: OneBotBot +) : OneBotBotStartedEvent { + 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/message/OneBotMessageEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent.kt index 5c79e14..4d0be93 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/message/OneBotMessageEvent.kt @@ -19,7 +19,7 @@ package love.forte.simbot.component.onebot.v11.core.event.message import love.forte.simbot.common.time.Timestamp import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot -import love.forte.simbot.component.onebot.v11.core.event.OneBotEvent +import love.forte.simbot.component.onebot.v11.core.event.OneBotBotEvent import love.forte.simbot.component.onebot.v11.core.utils.timestamp import love.forte.simbot.component.onebot.v11.message.OneBotMessageContent import love.forte.simbot.component.onebot.v11.message.OneBotMessageReceipt @@ -39,7 +39,7 @@ public typealias OBSourceMessageEvent = love.forte.simbot.component.onebot.v11.e * * @author ForteScarlet */ -public interface OneBotMessageEvent : OneBotEvent, MessageEvent { +public interface OneBotMessageEvent : OneBotBotEvent, MessageEvent { override val bot: OneBotBot override val sourceEvent: OBSourceMessageEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/notice/OneBotNoticeEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/notice/OneBotNoticeEvent.kt index 1aff54f..06b9fde 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/notice/OneBotNoticeEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/notice/OneBotNoticeEvent.kt @@ -17,13 +17,13 @@ package love.forte.simbot.component.onebot.v11.core.event.notice -import love.forte.simbot.component.onebot.v11.core.event.OneBotEvent +import love.forte.simbot.component.onebot.v11.core.event.OneBotBotEvent /** * * @author ForteScarlet */ -public interface OneBotNoticeEvent : OneBotEvent { +public interface OneBotNoticeEvent : OneBotBotEvent { // TODO } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/request/OneBotRequestEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/request/OneBotRequestEvent.kt index f2c0fa1..4e0cf1f 100644 --- a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/request/OneBotRequestEvent.kt +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/request/OneBotRequestEvent.kt @@ -17,13 +17,13 @@ package love.forte.simbot.component.onebot.v11.core.event.request -import love.forte.simbot.component.onebot.v11.core.event.OneBotEvent +import love.forte.simbot.component.onebot.v11.core.event.OneBotBotEvent /** * * @author ForteScarlet */ -public interface OneBotRequestEvent : OneBotEvent { +public interface OneBotRequestEvent : OneBotBotEvent { // TODO } diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/stage/OneBotBotStageEvent.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/stage/OneBotBotStageEvent.kt new file mode 100644 index 0000000..e78999a --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/event/stage/OneBotBotStageEvent.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024. 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.stage + +import love.forte.simbot.bot.BotManager +import love.forte.simbot.component.onebot.v11.core.bot.OneBotBot +import love.forte.simbot.component.onebot.v11.core.event.OneBotCommonEvent +import love.forte.simbot.event.BotRegisteredEvent +import love.forte.simbot.event.BotStageEvent +import love.forte.simbot.event.BotStartedEvent + + +/** + * OneBot组件中对 [BotStageEvent] 事件的实现类型。 + * + * @author ForteScarlet + */ +public interface OneBotBotStageEvent : BotStageEvent, OneBotCommonEvent { + override val bot: OneBotBot +} + +/** + * 当一个 Bot 已经在某个 [BotManager] 中被注册后的事件。 + * + * @author ForteScarlet + */ +public interface OneBotBotRegisteredEvent : OneBotBotStageEvent, BotRegisteredEvent + +/** + * 当一个 Bot **首次** 启动成功后的事件。 + * + * @author ForteScarlet + */ +public interface OneBotBotStartedEvent : OneBotBotStageEvent, BotStartedEvent diff --git a/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/EventPushLogs.kt b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/EventPushLogs.kt new file mode 100644 index 0000000..c668205 --- /dev/null +++ b/simbot-component-onebot-v11/simbot-component-onebot-v11-core/src/commonMain/kotlin/love/forte/simbot/component/onebot/v11/core/utils/EventPushLogs.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024. 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.utils + +import kotlinx.coroutines.flow.Flow +import love.forte.simbot.event.EventResult +import love.forte.simbot.event.onEachError +import love.forte.simbot.logger.Logger + +internal inline fun Flow.onEachErrorLog( + logger: Logger +): Flow = onEachError { err -> + logger.error( + "Event process with an error result: {}", + err.content.message, + err.content + ) +}