From 505943cb3d957f1abd2b7e5e79704417fd3b6249 Mon Sep 17 00:00:00 2001
From: Him188 <Him188@mamoe.net>
Date: Sat, 11 Apr 2020 16:05:29 +0800
Subject: [PATCH] Handle SMS login

---
 .../qqandroid/network/QQAndroidBotNetworkHandler.kt | 13 +++++++++++--
 .../network/protocol/packet/login/WtLogin.kt        |  2 +-
 .../net.mamoe.mirai/network/LoginFailedException.kt |  7 +++++++
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
index 2ada44bd3..fe9fb1343 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
@@ -23,6 +23,7 @@ import net.mamoe.mirai.event.events.BotOnlineEvent
 import net.mamoe.mirai.message.FriendMessage
 import net.mamoe.mirai.message.GroupMessage
 import net.mamoe.mirai.network.BotNetworkHandler
+import net.mamoe.mirai.network.UnsupportedSMSLoginException
 import net.mamoe.mirai.network.WrongPasswordException
 import net.mamoe.mirai.qqandroid.QQAndroidBot
 import net.mamoe.mirai.qqandroid.contact.FriendInfoImpl
@@ -105,6 +106,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
         }.also { heartbeatJob = it }
     }
 
+    @OptIn(MiraiExperimentalAPI::class)
     override suspend fun relogin(cause: Throwable?) {
         heartbeatJob?.cancel(CancellationException("relogin", cause))
         heartbeatJob?.join()
@@ -163,9 +165,15 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
                 }
 
                 is WtLogin.Login.LoginPacketResponse.Success -> {
-                    logger.info("Login successful")
+                    logger.info { "Login successful" }
                     break@mainloop
                 }
+
+                is WtLogin.Login.LoginPacketResponse.SMSVerifyCodeNeeded -> {
+                    val message = "SMS required: $response, which isn't yet supported"
+                    logger.error(message)
+                    throw UnsupportedSMSLoginException(message)
+                }
             }
         }
 
@@ -600,7 +608,8 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
     internal val packetListeners = LockFreeLinkedList<PacketListener>()
 
     @PublishedApi
-    internal inner class PacketListener( // callback
+    internal inner class PacketListener(
+        // callback
         val commandName: String,
         val sequenceId: Int
     ) : CompletableDeferred<Packet?> by CompletableDeferred(supervisor) {
diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/WtLogin.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/WtLogin.kt
index 7a2ee8eb0..70c7d7fca 100644
--- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/WtLogin.kt
+++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/WtLogin.kt
@@ -300,7 +300,7 @@ internal class WtLogin {
 
             class SMSVerifyCodeNeeded(val t402: ByteArray, val t403: ByteArray) : LoginPacketResponse() {
                 override fun toString(): String {
-                    return "LoginPacketResponse.SMSVerifyCodeNeeded"
+                    return "LoginPacketResponse.SMSVerifyCodeNeeded(t402=${t402.toUHexString()}, t403=${t403.toUHexString()})"
                 }
             }
 
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/LoginFailedException.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/LoginFailedException.kt
index 370b1ee88..3d9cc2254 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/LoginFailedException.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/LoginFailedException.kt
@@ -12,6 +12,7 @@
 package net.mamoe.mirai.network
 
 import net.mamoe.mirai.Bot
+import net.mamoe.mirai.utils.MiraiExperimentalAPI
 
 /**
  * 在 [登录][Bot.login] 失败时抛出, 可正常地中断登录过程.
@@ -28,6 +29,12 @@ sealed class LoginFailedException : RuntimeException {
  */
 class WrongPasswordException(message: String?) : LoginFailedException(message)
 
+/**
+ * 需要短信验证时抛出. mirai 目前还不支持短信验证.
+ */
+@MiraiExperimentalAPI
+class UnsupportedSMSLoginException(message: String?) : LoginFailedException(message)
+
 /**
  * 非 mirai 实现的异常
  */