commonMain.network.components.PacketHandler.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mirai-core-jvm Show documentation
Show all versions of mirai-core-jvm Show documentation
Mirai Protocol implementation for QQ Android
/*
* 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.BroadcastControllable
import net.mamoe.mirai.event.CancellableEvent
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.MultiPacket
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.component.ComponentKey
import net.mamoe.mirai.internal.network.component.ComponentStorage
import net.mamoe.mirai.internal.network.protocol.packet.*
import net.mamoe.mirai.utils.Either.Companion.ifRight
import net.mamoe.mirai.utils.Either.Companion.onRight
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.cast
import kotlin.coroutines.cancellation.CancellationException
internal interface PacketHandler {
suspend fun handlePacket(incomingPacket: IncomingPacket)
companion object : ComponentKey
}
internal class PacketHandlerChain(
private val instances: Collection
) : PacketHandler {
constructor(vararg instances: PacketHandler?) : this(instances.filterNotNull())
constructor(instances: Iterable) : this(instances.filterNotNull())
override suspend fun handlePacket(incomingPacket: IncomingPacket) {
for (instance in instances) {
try {
instance.handlePacket(incomingPacket)
} catch (e: Throwable) {
if (e is CancellationException) return
throw ExceptionInPacketHandlerException(instance, incomingPacket, e)
}
}
}
}
internal data class ExceptionInPacketHandlerException(
val packetHandler: PacketHandler,
val incomingPacket: IncomingPacket,
override val cause: Throwable,
) : IllegalStateException("Exception in PacketHandler '$packetHandler' for command '${incomingPacket.commandName}'.")
internal class LoggingPacketHandlerAdapter(
private val strategy: PacketLoggingStrategy,
private val logger: MiraiLogger,
) : PacketHandler {
override suspend fun handlePacket(incomingPacket: IncomingPacket) {
strategy.logReceived(logger, incomingPacket)
}
override fun toString(): String = "LoggingPacketHandlerAdapter"
}
internal class EventBroadcasterPacketHandler(
private val components: ComponentStorage,
) : PacketHandler {
override suspend fun handlePacket(incomingPacket: IncomingPacket) {
incomingPacket.result.ifRight(::impl)
}
private fun impl(packet: Packet?) {
if (packet == null) return
if (packet is MultiPacket) {
for (p in packet.children()) {
impl(p)
}
}
when {
packet is CancellableEvent && packet.isCancelled -> return
packet is BroadcastControllable && !packet.shouldBroadcast -> return
packet is Event -> {
components[EventDispatcher].broadcastAsync(packet)
}
}
}
override fun toString(): String = "EventBroadcasterPacketHandler"
}
internal class CallPacketFactoryPacketHandler(
private val bot: QQAndroidBot,
) : PacketHandler {
override suspend fun handlePacket(incomingPacket: IncomingPacket) {
incomingPacket.result.onRight { data ->
val factory = KnownPacketFactories.findPacketFactory(incomingPacket.commandName) ?: return
factory.cast>().run {
when (this) {
is IncomingPacketFactory -> {
val r = bot.handle(data, incomingPacket.sequenceId)
if (r != null) {
bot.network.sendWithoutExpect(r)
}
}
is OutgoingPacketFactory -> bot.handle(data)
}
}
}
}
override fun toString(): String = "CallPacketFactoryPacketHandler"
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy