From a7a4879d0541d8198ccedc9a5c735e3e03d1a44d Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 25 Apr 2021 18:37:21 +0800 Subject: [PATCH] Improve logging --- .../src/commonMain/kotlin/event/Event.kt | 17 +++- .../internal/event/InternalEventListeners.kt | 95 ++++++++----------- .../kotlin/internal/utils/StdoutLogger.kt | 2 +- .../commonMain/kotlin/utils/MiraiLogger.kt | 4 +- .../kotlin/utils/PlatformLogger.jvm.kt | 2 +- .../src/commonMain/kotlin/QQAndroidBot.kt | 3 +- .../src/commonMain/kotlin/network/Packet.kt | 8 +- .../network/components/PacketHandler.kt | 41 ++++---- .../components/PacketLoggingStrategy.kt | 80 ++++++++++++++++ .../kotlin/network/handler/NetworkHandler.kt | 3 +- .../network/handler/NetworkHandlerSupport.kt | 7 +- .../selector/SelectorNetworkHandler.kt | 4 + .../network/impl/netty/NettyNetworkHandler.kt | 28 +++--- .../kotlin/network/impl/netty/nettyUtils.kt | 6 ++ .../chat/receive/MessageSvc.PbGetMsg.kt | 31 +++--- .../AbstractRealNetworkHandlerTest.kt | 3 +- 16 files changed, 210 insertions(+), 124 deletions(-) create mode 100644 mirai-core/src/commonMain/kotlin/network/components/PacketLoggingStrategy.kt diff --git a/mirai-core-api/src/commonMain/kotlin/event/Event.kt b/mirai-core-api/src/commonMain/kotlin/event/Event.kt index 5408c99aa..e7efbb41c 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/Event.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/Event.kt @@ -15,7 +15,8 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import net.mamoe.mirai.event.events.BotEvent -import net.mamoe.mirai.internal.event.broadcastInternal +import net.mamoe.mirai.event.events.MessageEvent +import net.mamoe.mirai.internal.event.callAndRemoveIfRequired import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.utils.JavaFriendlyAPI import net.mamoe.mirai.utils.MiraiExperimentalApi @@ -143,26 +144,32 @@ public interface CancellableEvent : Event { * @see __broadcastJava Java 使用 */ @JvmSynthetic -public suspend fun E.broadcast(): E = apply { +public suspend fun E.broadcast(): E { check(this is AbstractEvent) { "Events must extend AbstractEvent" } if (this is BroadcastControllable && !this.shouldBroadcast) { - return@apply + return this } this.broadCastLock.withLock { this._intercepted = false if (EventDisabled) return@withLock if (this is Packet.NoEventLog) return@withLock - if (this is Packet) return@withLock // all [Packet]s are logged in [LoggingPacketHandler] + if (this is Packet.NoLog) return@withLock + if (this is MessageEvent) return@withLock // specially handled in [LoggingPacketHandlerAdapter] +// if (this is Packet) return@withLock // all [Packet]s are logged in [LoggingPacketHandlerAdapter] + if (this is BotEvent) { this.bot.logger.verbose { "Event: $this" } } else { MiraiLogger.TopLevel.verbose { "Event: $this" } } - this.broadcastInternal() // inline, no extra cost + + callAndRemoveIfRequired(this) } + + return this } /** diff --git a/mirai-core-api/src/commonMain/kotlin/internal/event/InternalEventListeners.kt b/mirai-core-api/src/commonMain/kotlin/internal/event/InternalEventListeners.kt index c43f1dd63..e6183ce5b 100644 --- a/mirai-core-api/src/commonMain/kotlin/internal/event/InternalEventListeners.kt +++ b/mirai-core-api/src/commonMain/kotlin/internal/event/InternalEventListeners.kt @@ -97,66 +97,53 @@ internal object GlobalEventListeners { } -// inline: NO extra Continuation -@Suppress("UNCHECKED_CAST") -internal suspend inline fun AbstractEvent.broadcastInternal() { - callAndRemoveIfRequired(this@broadcastInternal) -} - -internal inline fun > T.forEach0(block: T.(E) -> Unit) { - forEach { block(it) } -} - -@Suppress("DuplicatedCode") -internal suspend inline fun callAndRemoveIfRequired( - event: E -) { +internal suspend fun callAndRemoveIfRequired(event: E) { for (p in EventPriority.prioritiesExcludedMonitor) { - GlobalEventListeners[p].forEach0 { registeredRegistry -> - if (event.isIntercepted) { - return - } - if (!registeredRegistry.type.isInstance(event)) return@forEach0 - val listener = registeredRegistry.listener - when (listener.concurrencyKind) { - ConcurrencyKind.LOCKED -> { - (listener as Handler).lock!!.withLock { - if (listener.onEvent(event) == ListeningStatus.STOPPED) { - remove(registeredRegistry) - } - } - } - ConcurrencyKind.CONCURRENT -> { - if (listener.onEvent(event) == ListeningStatus.STOPPED) { - remove(registeredRegistry) - } - } + val container = GlobalEventListeners[p] + for (registry in container) { + if (event.isIntercepted) return + if (!registry.type.isInstance(event)) continue + val listener = registry.listener + process(container, registry, listener, event) + } + } + + if (event.isIntercepted) return + val container = GlobalEventListeners[EventPriority.MONITOR] + when (container.size) { + 0 -> return + 1 -> { + val registry = container.firstOrNull() ?: return + if (!registry.type.isInstance(event)) return + process(container, registry, registry.listener, event) + } + else -> supervisorScope { + for (registry in GlobalEventListeners[EventPriority.MONITOR]) { + if (!registry.type.isInstance(event)) continue + launch { process(container, registry, registry.listener, event) } } } } - coroutineScope { - GlobalEventListeners[EventPriority.MONITOR].forEach0 { registeredRegistry -> - if (event.isIntercepted) { - return@coroutineScope - } - if (!registeredRegistry.type.isInstance(event)) return@forEach0 - val listener = registeredRegistry.listener - launch { - when (listener.concurrencyKind) { - ConcurrencyKind.LOCKED -> { - (listener as Handler).lock!!.withLock { - if (listener.onEvent(event) == ListeningStatus.STOPPED) { - remove(registeredRegistry) - } - } - } - ConcurrencyKind.CONCURRENT -> { - if (listener.onEvent(event) == ListeningStatus.STOPPED) { - remove(registeredRegistry) - } - } +} + +private suspend fun process( + container: ConcurrentLinkedQueue, + registry: ListenerRegistry, + listener: Listener, + event: E, +) { + when (listener.concurrencyKind) { + ConcurrencyKind.LOCKED -> { + (listener as Handler).lock!!.withLock { + if (listener.onEvent(event) == ListeningStatus.STOPPED) { + container.remove(registry) } } } + ConcurrencyKind.CONCURRENT -> { + if (listener.onEvent(event) == ListeningStatus.STOPPED) { + container.remove(registry) + } + } } } \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/internal/utils/StdoutLogger.kt b/mirai-core-api/src/commonMain/kotlin/internal/utils/StdoutLogger.kt index fae3b9b8a..33ee75c4b 100644 --- a/mirai-core-api/src/commonMain/kotlin/internal/utils/StdoutLogger.kt +++ b/mirai-core-api/src/commonMain/kotlin/internal/utils/StdoutLogger.kt @@ -27,7 +27,7 @@ import java.util.* * * 示例: * ```log - * 2020-05-21 19:51:09 V/Bot 1994701021: Send: OidbSvc.0x88d_7 + * 2020-05-21 19:51:09 V/Bot 123456789: Send: OidbSvc.0x88d_7 * ``` * * 日期时间格式为 `yyyy-MM-dd HH:mm:ss`, diff --git a/mirai-core-api/src/commonMain/kotlin/utils/MiraiLogger.kt b/mirai-core-api/src/commonMain/kotlin/utils/MiraiLogger.kt index 1fe680c40..839ed5d52 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/MiraiLogger.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/MiraiLogger.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 Mamoe Technologies and contributors. + * Copyright 2019-2021 Mamoe Technologies and contributors. * * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. @@ -234,7 +234,7 @@ public inline fun MiraiLogger.error(message: () -> String?, e: Throwable?) { * * 示例: * ```log - * 2020-05-21 19:51:09 V/Bot 1994701021: Send: OidbSvc.0x88d_7 + * 2020-05-21 19:51:09 V/Bot 123456789: Send: OidbSvc.0x88d_7 * ``` * * 日期时间格式为 `yyyy-MM-dd HH:mm:ss`, diff --git a/mirai-core-api/src/jvmMain/kotlin/utils/PlatformLogger.jvm.kt b/mirai-core-api/src/jvmMain/kotlin/utils/PlatformLogger.jvm.kt index a5c00c549..58b7a13b4 100644 --- a/mirai-core-api/src/jvmMain/kotlin/utils/PlatformLogger.jvm.kt +++ b/mirai-core-api/src/jvmMain/kotlin/utils/PlatformLogger.jvm.kt @@ -27,7 +27,7 @@ import java.util.* * * 示例: * ```log - * 2020-05-21 19:51:09 V/Bot 1994701021: Send: OidbSvc.0x88d_7 + * 2020-05-21 19:51:09 V/Bot 123456789: Send: OidbSvc.0x88d_7 * ``` * * 日期时间格式为 `yyyy-MM-dd HH:mm:ss`, diff --git a/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt b/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt index 9dd82469c..e9bda5c57 100644 --- a/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt +++ b/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt @@ -163,9 +163,10 @@ internal open class QQAndroidBot constructor( set(ContactUpdater, ContactUpdaterImpl(bot, components, networkLogger)) set(BdhSessionSyncer, BdhSessionSyncerImpl(configuration, networkLogger, components)) set(ServerList, ServerListImpl()) + set(PacketLoggingStrategy, PacketLoggingStrategyImpl(bot)) set( PacketHandler, PacketHandlerChain( - LoggingPacketHandler(bot, networkLogger), + LoggingPacketHandlerAdapter(networkLogger, get(PacketLoggingStrategy)), EventBroadcasterPacketHandler(networkLogger), CallPacketFactoryPacketHandler(bot) ) diff --git a/mirai-core/src/commonMain/kotlin/network/Packet.kt b/mirai-core/src/commonMain/kotlin/network/Packet.kt index b3b2a4bdc..ce6bce384 100644 --- a/mirai-core/src/commonMain/kotlin/network/Packet.kt +++ b/mirai-core/src/commonMain/kotlin/network/Packet.kt @@ -9,7 +9,7 @@ package net.mamoe.mirai.internal.network -import net.mamoe.mirai.internal.QQAndroidBot +import net.mamoe.mirai.internal.AbstractBot import net.mamoe.mirai.internal.network.handler.logger import net.mamoe.mirai.utils.MiraiLogger @@ -52,12 +52,12 @@ internal class ParseErrorPacket( ) : Packet, Packet.NoLog { enum class Direction { TO_BOT_LOGGER { - override fun getLogger(bot: QQAndroidBot): MiraiLogger = bot.logger + override fun getLogger(bot: AbstractBot): MiraiLogger = bot.logger }, TO_NETWORK_LOGGER { - override fun getLogger(bot: QQAndroidBot): MiraiLogger = bot.network.logger + override fun getLogger(bot: AbstractBot): MiraiLogger = bot.network.logger }; - abstract fun getLogger(bot: QQAndroidBot): MiraiLogger + abstract fun getLogger(bot: AbstractBot): MiraiLogger } } diff --git a/mirai-core/src/commonMain/kotlin/network/components/PacketHandler.kt b/mirai-core/src/commonMain/kotlin/network/components/PacketHandler.kt index 01dc13e32..9521a3294 100644 --- a/mirai-core/src/commonMain/kotlin/network/components/PacketHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/components/PacketHandler.kt @@ -13,17 +13,13 @@ import net.mamoe.mirai.event.BroadcastControllable import net.mamoe.mirai.event.CancellableEvent import net.mamoe.mirai.event.Event import net.mamoe.mirai.event.broadcast -import net.mamoe.mirai.event.events.MessageEvent import net.mamoe.mirai.internal.QQAndroidBot -import net.mamoe.mirai.internal.contact.logMessageReceived -import net.mamoe.mirai.internal.contact.replaceMagicCodes +import net.mamoe.mirai.internal.network.MultiPacket import net.mamoe.mirai.internal.network.Packet -import net.mamoe.mirai.internal.network.ParseErrorPacket import net.mamoe.mirai.internal.network.component.ComponentKey import net.mamoe.mirai.internal.network.protocol.packet.* import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.cast -import net.mamoe.mirai.utils.verbose internal interface PacketHandler { suspend fun handlePacket(incomingPacket: IncomingPacket) @@ -53,29 +49,15 @@ internal data class ExceptionInPacketHandlerException( override val cause: Throwable, ) : IllegalStateException("Exception in PacketHandler '$packetHandler'.") -internal class LoggingPacketHandler( - private val bot: QQAndroidBot, +internal class LoggingPacketHandlerAdapter( private val logger: MiraiLogger, + private val strategy: PacketLoggingStrategy, ) : PacketHandler { override suspend fun handlePacket(incomingPacket: IncomingPacket) { - val packet = incomingPacket.data ?: return - if (!bot.logger.isEnabled && !logger.isEnabled) return - when { - packet is ParseErrorPacket -> { - packet.direction.getLogger(bot).error(packet.error) - } - packet is MessageEvent -> packet.logMessageReceived() - packet is Packet.NoLog -> { - // nothing to do - } - packet is Event && packet !is Packet.NoEventLog -> bot.logger.verbose { - "Event: $packet".replaceMagicCodes() - } - else -> logger.verbose { "Recv: ${incomingPacket.commandName} ${incomingPacket.data}".replaceMagicCodes() } - } + strategy.logReceived(logger, incomingPacket) } - override fun toString(): String = "LoggingPacketHandler" + override fun toString(): String = "LoggingPacketHandlerAdapter" } internal class EventBroadcasterPacketHandler( @@ -83,7 +65,16 @@ internal class EventBroadcasterPacketHandler( ) : PacketHandler { override suspend fun handlePacket(incomingPacket: IncomingPacket) { - val packet = incomingPacket.data ?: return + val data = incomingPacket.data ?: return + impl(data) + } + + private suspend fun impl(packet: Packet) { + if (packet is MultiPacket<*>) { + for (p in packet) { + impl(p) + } + } when { packet is CancellableEvent && packet.isCancelled -> return packet is BroadcastControllable && !packet.shouldBroadcast -> return @@ -105,7 +96,7 @@ internal class EventBroadcasterPacketHandler( return qualified.substringAfter("net.mamoe.mirai.event.events.") } - override fun toString(): String = "LoggingPacketHandler" + override fun toString(): String = "EventBroadcasterPacketHandler" } internal class CallPacketFactoryPacketHandler( diff --git a/mirai-core/src/commonMain/kotlin/network/components/PacketLoggingStrategy.kt b/mirai-core/src/commonMain/kotlin/network/components/PacketLoggingStrategy.kt new file mode 100644 index 000000000..103a15e90 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/components/PacketLoggingStrategy.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2019-2021 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.components + +import net.mamoe.mirai.event.Event +import net.mamoe.mirai.event.events.MessageEvent +import net.mamoe.mirai.internal.AbstractBot +import net.mamoe.mirai.internal.contact.logMessageReceived +import net.mamoe.mirai.internal.contact.replaceMagicCodes +import net.mamoe.mirai.internal.network.Packet +import net.mamoe.mirai.internal.network.ParseErrorPacket +import net.mamoe.mirai.internal.network.component.ComponentKey +import net.mamoe.mirai.internal.network.protocol.packet.IncomingPacket +import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket +import net.mamoe.mirai.utils.MiraiLogger +import net.mamoe.mirai.utils.systemProp +import net.mamoe.mirai.utils.verbose + +/** + * Implementation must be fast and non-blocking, throwing no exception. + */ +internal interface PacketLoggingStrategy { + fun logSent(logger: MiraiLogger, outgoingPacket: OutgoingPacket) + fun logReceived(logger: MiraiLogger, incomingPacket: IncomingPacket) + + companion object : ComponentKey +} + +internal class PacketLoggingStrategyImpl( + private val bot: AbstractBot, + private val blacklist: Set = DEFAULT_BLACKLIST, +) : PacketLoggingStrategy { + override fun logSent(logger: MiraiLogger, outgoingPacket: OutgoingPacket) { + if (outgoingPacket.commandName in blacklist) return + logger.verbose { "Send: ${outgoingPacket.commandName}" } + } + + override fun logReceived(logger: MiraiLogger, incomingPacket: IncomingPacket) { + val packet = incomingPacket.data ?: return + if (!bot.logger.isEnabled && !logger.isEnabled) return + when { + packet is ParseErrorPacket -> { + packet.direction.getLogger(bot).error(packet.error) + } + packet is MessageEvent -> packet.logMessageReceived() + packet is Packet.NoLog -> { + // nothing to do + } + packet is Event && packet !is Packet.NoEventLog -> bot.logger.verbose { + "Event: $packet".replaceMagicCodes() + } + else -> { + if (SHOW_PACKET_DETAILS) { + logger.verbose { "Recv: ${incomingPacket.commandName} ${incomingPacket.data}".replaceMagicCodes() } + } else { + logger.verbose { "Recv: ${incomingPacket.commandName}".replaceMagicCodes() } + } + } + } + } + + companion object { + @JvmField + val DEFAULT_BLACKLIST = setOf( + "MessageSvc.PbDeleteMsg", + "MessageSvc.PbGetMsg", // they are too verbose. + "OnlinePush.RespPush" + ) + + @JvmField + var SHOW_PACKET_DETAILS = systemProp("mirai.debug.network.show.packet.details", false) + } +} diff --git a/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt index 0496a1e9a..3c1281171 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt @@ -9,6 +9,7 @@ package net.mamoe.mirai.internal.network.handler +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.selects.SelectClause1 import net.mamoe.mirai.Bot import net.mamoe.mirai.internal.network.Packet @@ -30,7 +31,7 @@ import net.mamoe.mirai.utils.MiraiLogger * @see NetworkHandlerSupport * @see NetworkHandlerFactory */ -internal interface NetworkHandler { +internal interface NetworkHandler : CoroutineScope { val context: NetworkHandlerContext fun isOk() = state == State.OK diff --git a/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandlerSupport.kt b/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandlerSupport.kt index 1781a1af7..108a8328f 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandlerSupport.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandlerSupport.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.selects.SelectClause1 import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.components.PacketCodec import net.mamoe.mirai.internal.network.components.PacketHandler +import net.mamoe.mirai.internal.network.components.PacketLoggingStrategy import net.mamoe.mirai.internal.network.components.RawIncomingPacket import net.mamoe.mirai.internal.network.handler.state.StateObserver import net.mamoe.mirai.internal.network.protocol.packet.IncomingPacket @@ -69,7 +70,7 @@ internal abstract class NetworkHandlerSupport( val listener = PacketListener(packet.commandName, packet.sequenceId) var exception: Throwable? = null repeat(attempts.coerceAtLeast(1)) { - logger.verbose { "Send: ${packet.commandName}" } + context[PacketLoggingStrategy].logSent(logger, packet) try { packetListeners.add(listener) sendPacketImpl(packet) @@ -92,7 +93,7 @@ internal abstract class NetworkHandlerSupport( } final override suspend fun sendWithoutExpect(packet: OutgoingPacket) { - logger.verbose { "Send: ${packet.commandName}" } + context[PacketLoggingStrategy].logSent(logger, packet) sendPacketImpl(packet) } @@ -102,7 +103,7 @@ internal abstract class NetworkHandlerSupport( // } else { // logger.info { "NetworkHandler '$this' closed: $cause" } // } - coroutineContext.job.cancel("NetworkHandler closed.", cause) + coroutineContext.job.cancel("NetworkHandler closed", cause) } protected val packetLogger: MiraiLogger by lazy { diff --git a/mirai-core/src/commonMain/kotlin/network/handler/selector/SelectorNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/handler/selector/SelectorNetworkHandler.kt index a6bf77943..36658989f 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/selector/SelectorNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/selector/SelectorNetworkHandler.kt @@ -18,6 +18,7 @@ import net.mamoe.mirai.internal.network.handler.NetworkHandler import net.mamoe.mirai.internal.network.handler.NetworkHandler.State import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket +import kotlin.coroutines.CoroutineContext /** * A proxy to [NetworkHandler] that delegates calls to instance returned by [NetworkHandlerSelector.awaitResumeInstance]. @@ -52,6 +53,9 @@ internal class SelectorNetworkHandler( selector.getResumedInstance()?.close(cause) } + override val coroutineContext: CoroutineContext + get() = selector.getResumedInstance()?.coroutineContext ?: scope.coroutineContext // merely use fallback + override fun toString(): String = "SelectorNetworkHandler(currentInstance=${selector.getResumedInstance()})" } diff --git a/mirai-core/src/commonMain/kotlin/network/impl/netty/NettyNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/impl/netty/NettyNetworkHandler.kt index 6f873960d..0eb16d834 100644 --- a/mirai-core/src/commonMain/kotlin/network/impl/netty/NettyNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/impl/netty/NettyNetworkHandler.kt @@ -81,7 +81,7 @@ internal open class NettyNetworkHandler( private inner class OutgoingPacketEncoder : MessageToByteEncoder(OutgoingPacket::class.java) { override fun encode(ctx: ChannelHandlerContext, msg: OutgoingPacket, out: ByteBuf) { - PacketCodec.PacketLogger.debug { "encode: $msg" } + packetLogger.debug { "encode: $msg" } out.writeBytes(msg.delegate) } } @@ -261,19 +261,29 @@ internal open class NettyNetworkHandler( connection.writeAndFlush(packet) } + private val configPush = this@NettyNetworkHandler.launch(CoroutineName("ConfigPush sync")) { + try { + context[ConfigPushProcessor].syncConfigPush(this@NettyNetworkHandler) + } catch (e: ConfigPushProcessor.RequireReconnectException) { + setState { StateConnecting(ExceptionCollector(e), false) } + } + } + override suspend fun resumeConnection0() { (coroutineContext.job as CompletableJob).run { complete() join() } - setState { StateOK(connection) } + joinCompleted(configPush) // throw exception + setState { StateOK(connection, configPush) } } // noop override fun toString(): String = "StateLoading" } protected inner class StateOK( - private val connection: NettyChannel + private val connection: NettyChannel, + private val configPush: Job, ) : NettyState(State.OK) { init { coroutineContext.job.invokeOnCompletion { @@ -307,14 +317,6 @@ internal open class NettyNetworkHandler( } } - private val configPush = launch(CoroutineName("ConfigPush sync")) { - try { - context[ConfigPushProcessor].syncConfigPush(this@NettyNetworkHandler) - } catch (e: ConfigPushProcessor.RequireReconnectException) { - setState { StateClosed(e) } - } - } - // we can also move them as observers if needed. private val keyRefresh = launch(CoroutineName("Key refresh")) { @@ -332,10 +334,6 @@ internal open class NettyNetworkHandler( joinCompleted(keyRefresh) } // noop - private suspend inline fun joinCompleted(job: Job) { - if (job.isCompleted) job.join() - } - override fun toString(): String = "StateOK" } diff --git a/mirai-core/src/commonMain/kotlin/network/impl/netty/nettyUtils.kt b/mirai-core/src/commonMain/kotlin/network/impl/netty/nettyUtils.kt index bc4904649..9d3168292 100644 --- a/mirai-core/src/commonMain/kotlin/network/impl/netty/nettyUtils.kt +++ b/mirai-core/src/commonMain/kotlin/network/impl/netty/nettyUtils.kt @@ -14,6 +14,7 @@ import io.netty.buffer.ByteBufInputStream import io.netty.channel.ChannelFuture import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.Job import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.SimpleLogger @@ -55,3 +56,8 @@ internal fun MiraiLogger.asCoroutineExceptionHandler( ) } } + + +internal suspend inline fun joinCompleted(job: Job) { + if (job.isCompleted) job.join() +} diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt index 9e9a26bb7..70c829fd2 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutines.sync.withLock import kotlinx.io.core.* +import net.mamoe.mirai.Bot import net.mamoe.mirai.Mirai import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.MemberPermission @@ -55,7 +56,10 @@ import net.mamoe.mirai.message.data.MessageSourceKind.STRANGER import net.mamoe.mirai.message.data.MessageSourceKind.TEMP import net.mamoe.mirai.message.data.PlainText import net.mamoe.mirai.message.data.buildMessageChain -import net.mamoe.mirai.utils.* +import net.mamoe.mirai.utils.cast +import net.mamoe.mirai.utils.debug +import net.mamoe.mirai.utils.read +import net.mamoe.mirai.utils.toUHexString import kotlin.random.Random @@ -93,12 +97,13 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory, syncCookie: ByteArray?, val bot: QQAndroidBot) : Response( + open class GetMsgSuccess(delegate: List, syncCookie: ByteArray?, bot: QQAndroidBot) : Response( MsgSvc.SyncFlag.STOP, delegate, - syncCookie + syncCookie, + bot ), Event, Packet.NoLog { - override fun toString(): String = "MessageSvcPbGetMsg.GetMsgSuccess(messages=))" + override fun toString(): String = "MessageSvcPbGetMsg.GetMsgSuccess" } /** @@ -107,15 +112,16 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory, - val syncCookie: ByteArray? + val syncCookie: ByteArray?, override val bot: Bot ) : AbstractEvent(), MultiPacket, Iterable by (delegate), - Packet.NoLog { + Packet.NoLog, + BotEvent { override fun toString(): String = - "MessageSvcPbGetMsg.Response(syncFlagFromServer=$syncFlagFromServer, messages=))" + "MessageSvcPbGetMsg.Response(flag=$syncFlagFromServer)" } class EmptyResponse( @@ -128,9 +134,12 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory : Abs set(ContactUpdater, ContactUpdaterImpl(bot, components, networkLogger)) set(BdhSessionSyncer, BdhSessionSyncerImpl(configuration, networkLogger, components)) set(ServerList, ServerListImpl()) - set(PacketHandler, LoggingPacketHandler(bot, networkLogger)) + set(PacketLoggingStrategy, PacketLoggingStrategyImpl(bot)) + set(PacketHandler, LoggingPacketHandlerAdapter(networkLogger, get(PacketLoggingStrategy))) set(PacketCodec, PacketCodecImpl()) set(OtherClientUpdater, OtherClientUpdaterImpl(bot, components, bot.logger)) set(ConfigPushSyncer, ConfigPushSyncerImpl())