From d1cc2710ec389f82a800b01b4182bc5bed14b488 Mon Sep 17 00:00:00 2001
From: Him188 <Him188@mamoe.net>
Date: Mon, 30 Sep 2019 03:24:53 +0800
Subject: [PATCH] Improved temporary packet handlers

---
 .../mirai/message/defaults/UnsolvedImage.kt    | 10 +++++++---
 .../mamoe/mirai/network/BotNetworkHandler.kt   |  5 ++---
 .../net/mamoe/mirai/network/LoginSession.kt    | 13 ++++---------
 .../protocol/tim/TIMBotNetworkHandler.kt       |  1 -
 .../tim/handler/TemporaryPacketHandler.kt      | 18 +++++++++++++++---
 5 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/UnsolvedImage.kt b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/UnsolvedImage.kt
index c2caaa6df..7fb5a3760 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/UnsolvedImage.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/UnsolvedImage.kt
@@ -1,5 +1,7 @@
 package net.mamoe.mirai.message.defaults
 
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
 import net.mamoe.mirai.contact.Contact
 import net.mamoe.mirai.network.LoginSession
 import net.mamoe.mirai.network.protocol.tim.packet.image.ClientTryGetImageIDPacket
@@ -30,7 +32,7 @@ class UnsolvedImage(filename: String, val image: BufferedImage) : Image(getImage
         return session.expectPacket<ServerTryGetImageIDResponsePacket> {
             toSend { ClientTryGetImageIDPacket(session.bot.account.qqNumber, session.sessionKey, contact.number, image) }
 
-            expect {
+            onExpect {
                 when (it) {
                     is ServerTryGetImageIDFailedPacket -> {
                         //已经存在于服务器了
@@ -38,8 +40,10 @@ class UnsolvedImage(filename: String, val image: BufferedImage) : Image(getImage
 
                     is ServerTryGetImageIDSuccessPacket -> {
                         val data = image.toByteArray()
-                        if (!ImageNetworkUtils.postImage(it.uKey.toUHexString(), data.size, session.bot.account.qqNumber, contact.number, data)) {
-                            throw RuntimeException("cannot upload image")
+                        withContext(Dispatchers.IO) {
+                            if (!ImageNetworkUtils.postImage(it.uKey.toUHexString(), data.size, session.bot.account.qqNumber, contact.number, data)) {
+                                throw RuntimeException("cannot upload image")
+                            }
                         }
                     }
                 }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/BotNetworkHandler.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/BotNetworkHandler.kt
index 4c7d69207..a4763f3b4 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/BotNetworkHandler.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/BotNetworkHandler.kt
@@ -6,7 +6,6 @@ import net.mamoe.mirai.network.protocol.tim.handler.ActionPacketHandler
 import net.mamoe.mirai.network.protocol.tim.handler.DataPacketSocket
 import net.mamoe.mirai.network.protocol.tim.handler.MessagePacketHandler
 import net.mamoe.mirai.network.protocol.tim.handler.TemporaryPacketHandler
-import net.mamoe.mirai.network.protocol.tim.internal.handler.*
 import net.mamoe.mirai.network.protocol.tim.packet.ClientPacket
 import net.mamoe.mirai.network.protocol.tim.packet.Packet
 import net.mamoe.mirai.network.protocol.tim.packet.ServerEventPacket
@@ -46,14 +45,14 @@ interface BotNetworkHandler : Closeable {
      *
      * java 调用方式: `botNetWorkHandler.getMessage()`
      */
-    var message: MessagePacketHandler
+    val message: MessagePacketHandler
 
     /**
      * 动作处理. 如发送好友请求, 处理别人发来的好友请求等
      *
      * java 调用方式: `botNetWorkHandler.getAction()`
      */
-    var action: ActionPacketHandler
+    val action: ActionPacketHandler
 
     fun tryLogin(touchingTimeoutMillis: Long = 200): CompletableFuture<LoginState>
 
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/LoginSession.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/LoginSession.kt
index 0bde28064..26b4a24eb 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/LoginSession.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/LoginSession.kt
@@ -42,13 +42,12 @@ class LoginSession(
 
     /**
      * 发送一个数据包, 并期待接受一个特定的 [ServerPacket].
-     * 发送成功后, 该方法会等待收到 [ServerPacket] 直到超时.
      *
      * 实现方法:
      * ```kotlin
      * session.expectPacket<ServerPacketXXX> {
      *  toSend { ClientPacketXXX(...) }
-     *  expect {//it: ServerPacketXXX
+     *  onExpect {//it: ServerPacketXXX
      *
      *  }
      * }
@@ -57,8 +56,6 @@ class LoginSession(
      * @param P 期待的包
      * @param handlerTemporary 处理器.
      * @return future. 可进行超时处理
-     *
-     * Kotlin DSL: 仅 Kotlin 使用.
      */
     @JvmSynthetic
     inline fun <reified P : ServerPacket> expectPacket(handlerTemporary: TemporaryPacketHandler<P>.() -> Unit): CompletableFuture<Unit> {
@@ -83,15 +80,13 @@ class LoginSession(
      * @param toSend 将要发送的包
      * @param handler 处理期待的包
      * @return future. 可进行超时处理
-     *
-     * Kotlin DSL: 仅 Kotlin 使用.
      */
     @JvmSynthetic
-    inline fun <reified P : ServerPacket> expectPacket(toSend: ClientPacket, noinline handler: (P) -> Unit): CompletableFuture<Unit> {
+    inline fun <reified P : ServerPacket> expectPacket(toSend: ClientPacket, noinline handler: suspend (P) -> Unit): CompletableFuture<Unit> {
         val future = CompletableFuture<Unit>()
         this.bot.network.addHandler(TemporaryPacketHandler(P::class, future, this).also {
-            it.toSend { toSend }
-            it.expect(handler)
+            it.toSend(toSend)
+            it.onExpect(handler)
         })
         return future
     }
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/protocol/tim/TIMBotNetworkHandler.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/protocol/tim/TIMBotNetworkHandler.kt
index 6938c1afb..8a6c938a5 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/protocol/tim/TIMBotNetworkHandler.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/protocol/tim/TIMBotNetworkHandler.kt
@@ -10,7 +10,6 @@ import net.mamoe.mirai.network.BotNetworkHandler
 import net.mamoe.mirai.network.LoginSession
 import net.mamoe.mirai.network.NetworkScope
 import net.mamoe.mirai.network.protocol.tim.handler.*
-import net.mamoe.mirai.network.protocol.tim.internal.handler.*
 import net.mamoe.mirai.network.protocol.tim.packet.*
 import net.mamoe.mirai.network.protocol.tim.packet.login.*
 import net.mamoe.mirai.task.MiraiThreadPool
diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt
index 8e4f918f2..c5cc63fe4 100644
--- a/mirai-core/src/main/java/net/mamoe/mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt
+++ b/mirai-core/src/main/java/net/mamoe/mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt
@@ -8,6 +8,14 @@ import kotlin.reflect.KClass
 
 /**
  * 临时数据包处理器
+ * ```kotlin
+ * session.addHandler<ClientTouchResponsePacket>{
+ *   toSend { ClientTouchPacket() }
+ *   onExpect {//it: ClientTouchResponsePacket
+ *      //do sth.
+ *   }
+ * }
+ * ```
  *
  * @see LoginSession.expectPacket
  */
@@ -18,7 +26,7 @@ open class TemporaryPacketHandler<P : ServerPacket>(
 ) {
     private lateinit var toSend: ClientPacket
 
-    private lateinit var expect: (P) -> Unit
+    private lateinit var expect: suspend (P) -> Unit
 
 
     lateinit var session: LoginSession//无需覆盖
@@ -27,8 +35,12 @@ open class TemporaryPacketHandler<P : ServerPacket>(
         this.toSend = packet()
     }
 
+    fun toSend(packet: ClientPacket) {
+        this.toSend = packet
+    }
 
-    fun expect(handler: (P) -> Unit) {
+
+    fun onExpect(handler: suspend (P) -> Unit) {
         this.expect = handler
     }
 
@@ -37,7 +49,7 @@ open class TemporaryPacketHandler<P : ServerPacket>(
         session.socket.sendPacket(toSend)
     }
 
-    fun onPacketReceived(session: LoginSession, packet: ServerPacket): Boolean {
+    suspend fun onPacketReceived(session: LoginSession, packet: ServerPacket): Boolean {
         if (expectationClass.isInstance(packet) && session === this.fromSession) {
             @Suppress("UNCHECKED_CAST")
             expect(packet as P)