diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt index d772630d4..694106920 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt @@ -213,14 +213,14 @@ Mirai 22:04:48 : Packet received: UnknownEventPacket(id=00 D6, identity=(2092749 * @param lazyMessage 若需要验证请求时的验证消息. */ suspend fun ContactSystem.addFriend(id: UInt, lazyMessage: () -> String = { "" }, lazyRemark: () -> String = { "" }): AddFriendResult = bot.withSession { - when (CanAddFriendPacket(bot.qqAccount, id, bot.sessionKey).sendAndExpect().await()) { + when (CanAddFriendPacket(bot.qqAccount, id, bot.sessionKey).sendAndExpect()) { is CanAddFriendResponse.AlreadyAdded -> AddFriendResult.ALREADY_ADDED is CanAddFriendResponse.Rejected -> AddFriendResult.REJECTED is CanAddFriendResponse.ReadyToAdd, is CanAddFriendResponse.RequireVerification -> { - val key = RequestFriendAdditionKeyPacket(bot.qqAccount, id, sessionKey).sendAndExpect().await().key - AddFriendPacket(bot.qqAccount, id, sessionKey, lazyMessage(), lazyRemark(), key).sendAndExpect().await() + val key = RequestFriendAdditionKeyPacket(bot.qqAccount, id, sessionKey).sendAndExpect().key + AddFriendPacket(bot.qqAccount, id, sessionKey, lazyMessage(), lazyRemark(), key).sendAndExpect() return AddFriendResult.WAITING_FOR_APPROVE } //这个做的是需要验证消息的情况, 不确定 ReadyToAdd 的是啥 @@ -232,13 +232,12 @@ suspend fun ContactSystem.addFriend(id: UInt, lazyMessage: () -> String = { "" } /*is CanAddFriendResponse.ReadyToAdd -> { // TODO: 2019/11/11 这不需要验证信息的情况 - //AddFriendPacket(bot.qqAccount, id, bot.sessionKey, ).sendAndExpect().await() + //AddFriendPacket(bot.qqAccount, id, bot.sessionKey, ).sendAndExpectAsync().await() TODO() }*/ } } - /* 1494695429 同意好友请求后收到以下包: diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotHelper.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotHelper.kt index 7a52fba52..06ff06ea3 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotHelper.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotHelper.kt @@ -41,7 +41,7 @@ inline val Bot.qqs: ContactList /** * 以 [BotSession] 作为接收器 (receiver) 并调用 [block], 返回 [block] 的返回值. - * 这个方法将能帮助使用在 [BotSession] 中定义的一些扩展方法, 如 [BotSession.sendAndExpect] + * 这个方法将能帮助使用在 [BotSession] 中定义的一些扩展方法, 如 [BotSession.sendAndExpectAsync] */ inline fun Bot.withSession(block: BotSession.() -> R): R = with(this.network.session) { block() } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt index dd7f0d8b5..2ad4baacb 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt @@ -104,7 +104,7 @@ class Group internal constructor(bot: Bot, val groupId: GroupId) : Contact(bot, /** * 以 [BotSession] 作为接收器 (receiver) 并调用 [block], 返回 [block] 的返回值. - * 这个方法将能帮助使用在 [BotSession] 中定义的一些扩展方法, 如 [BotSession.sendAndExpect] + * 这个方法将能帮助使用在 [BotSession] 中定义的一些扩展方法, 如 [BotSession.sendAndExpectAsync] */ inline fun Contact.withSession(block: BotSession.() -> R): R = bot.withSession(block) @@ -138,7 +138,7 @@ open class QQ internal constructor(bot: Bot, id: UInt) : Contact(bot, id) { */ suspend fun updateProfile(): Profile = bot.withSession { RequestProfileDetailsPacket(bot.qqAccount, id, sessionKey) - .sendAndExpect { it.profile } + .sendAndExpectAsync { it.profile } .await().let { @Suppress("UNCHECKED_CAST") if ((::profile as SuspendLazy).isInitialized()) { diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt index a3eb30887..e96526bee 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt @@ -66,7 +66,7 @@ interface BotNetworkHandler : CoroutineScope { /** * 添加一个临时包处理器, 并发送相应的包 * - * @see [BotSession.sendAndExpect] 发送并期待一个包 + * @see [BotSession.sendAndExpectAsync] 发送并期待一个包 * @see [TemporaryPacketHandler] 临时包处理器 */ suspend fun addHandler(temporaryPacketHandler: TemporaryPacketHandler<*, *>) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt index 7037e9476..7325cc890 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt @@ -4,6 +4,7 @@ package net.mamoe.mirai.network import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred import kotlinx.coroutines.Job import net.mamoe.mirai.Bot import net.mamoe.mirai.contact.Group @@ -75,7 +76,7 @@ class BotSession( * 实现方法: * ```kotlin * with(session){ - * ClientPacketXXX(...).sendAndExpect { + * ClientPacketXXX(...).sendAndExpectAsync { * //it: ServerPacketXXX * } * } @@ -84,14 +85,14 @@ class BotSession( * * @param checkSequence 是否筛选 `sequenceId`, 即是否筛选发出的包对应的返回包. * @param P 期待的包 - * @param handler 处理期待的包. 将会在调用本函数的 [coroutineContext] 下执行. + * @param handler 处理期待的包. **将会在调用本函数的 [coroutineContext] 下执行.** * - * @see Bot.withSession 转换接收器 (receiver, 即 `this` 的指向) 为 [BotSession] + * @see Bot.withSession 转换 receiver, 即 `this` 的指向, 为 [BotSession] */ - suspend inline fun OutgoingPacket.sendAndExpect( + suspend inline fun OutgoingPacket.sendAndExpectAsync( checkSequence: Boolean = true, noinline handler: suspend (P) -> R - ): CompletableDeferred { + ): Deferred { val deferred: CompletableDeferred = CompletableDeferred(coroutineContext[Job]) bot.network.addHandler(TemporaryPacketHandler(P::class, deferred, this@BotSession, checkSequence, coroutineContext + deferred).also { it.toSend(this) @@ -103,9 +104,36 @@ class BotSession( /** * 发送一个数据包, 并期待接受一个特定的 [ServerPacket][P]. * 将能从本函数的返回值 [CompletableDeferred] 接收到所期待的 [P] + * 本函数将能帮助实现清晰的包处理逻辑 + * + * 实现方法: + * ```kotlin + * with(session){ + * val deferred = ClientPacketXXX(...).sendAndExpectAsync() + * // do something + * + * deferred.await() // or deferred.join() + * } + * ``` */ - suspend inline fun OutgoingPacket.sendAndExpect(checkSequence: Boolean = true): CompletableDeferred

= - sendAndExpect(checkSequence) { it } + suspend inline fun OutgoingPacket.sendAndExpectAsync(checkSequence: Boolean = true): Deferred

= + sendAndExpectAsync(checkSequence) { it } + + /** + * 发送一个数据包, 并期待接受一个特定的 [ServerPacket][P]. + * 将调用 [CompletableDeferred.await], 挂起等待接收到指定的包后才返回. + * 本函数将能帮助实现清晰的包处理逻辑 + * + * 实现方法: + * ```kotlin + * with(session){ + * val packet:AddFriendPacket.Response = AddFriendPacket(...).sendAndExpect() + * } + * ``` + * @sample Bot.addFriend 添加好友 + */ + suspend inline fun OutgoingPacket.sendAndExpect(checkSequence: Boolean = true): P = + sendAndExpectAsync(checkSequence) { it }.await() suspend inline fun OutgoingPacket.send() = socket.sendPacket(this) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt index a8ce10e8d..128041bbb 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt @@ -513,7 +513,7 @@ internal class TIMBotNetworkHandler internal constructor(override inline val bot HeartbeatPacket( bot.qqAccount, sessionKey - ).sendAndExpect().join() + ).sendAndExpectAsync().join() } == null) { bot.logger.warning("Heartbeat timed out") bot.reinitializeNetworkHandler(configuration, HeartbeatTimeoutException()) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/DataPacketSocketAdapter.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/DataPacketSocketAdapter.kt index 2f4df43bf..9cd1b48e1 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/DataPacketSocketAdapter.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/DataPacketSocketAdapter.kt @@ -41,7 +41,7 @@ interface DataPacketSocketAdapter : Closeable { * * 可通过 hook 事件 [ServerPacketReceivedEvent] 来获取服务器返回. * - * @see [BotSession.sendAndExpect] kotlin DSL + * @see [BotSession.sendAndExpectAsync] kotlin DSL */ suspend fun sendPacket(packet: OutgoingPacket) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt index e670d90d6..3caa60b04 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt @@ -21,7 +21,7 @@ import kotlin.reflect.KClass * } * ``` * - * @see BotSession.sendAndExpect + * @see BotSession.sendAndExpectAsync */ class TemporaryPacketHandler

( private val expectationClass: KClass

, diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/UploadImage.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/UploadImage.kt index 9c37f34c8..753507315 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/UploadImage.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/UploadImage.kt @@ -37,7 +37,7 @@ class OverFileSizeMaxException : IllegalStateException() suspend fun Group.uploadImage(image: ExternalImage): ImageId = withSession { val userContext = coroutineContext GroupImageIdRequestPacket(bot.qqAccount, internalId, image, sessionKey) - .sendAndExpect { + .sendAndExpectAsync { withContext(userContext) { when (it) { is GroupImageIdRequestPacket.Response.RequireUpload -> httpClient.postImage( @@ -69,8 +69,8 @@ suspend fun Group.uploadImage(image: ExternalImage): ImageId = withSession { */ suspend fun QQ.uploadImage(image: ExternalImage): ImageId = bot.withSession { FriendImageIdRequestPacket(qqAccount, sessionKey, id, image) - .sendAndExpect { - return@sendAndExpect when (it) { + .sendAndExpectAsync { + return@sendAndExpectAsync when (it) { is FriendImageIdRequestPacket.Response.RequireUpload -> { httpClient.postImage( htcmd = "0x6ff0070", diff --git a/mirai-debug/src/main/kotlin/PacketDebuger.kt b/mirai-debug/src/main/kotlin/PacketDebuger.kt index 21801388a..ec9800967 100644 --- a/mirai-debug/src/main/kotlin/PacketDebuger.kt +++ b/mirai-debug/src/main/kotlin/PacketDebuger.kt @@ -312,7 +312,7 @@ internal object DebugNetworkHandler : BotNetworkHandler get() = bot } - override val bot: Bot = Bot(0u, "") + override val bot: Bot = Bot(qq, "") val session = BotSession(bot, sessionKey, socket, this) val action = ActionPacketHandler(session)