From fb3fe2bcca650597d24156f5e463ed6fd8e5564e Mon Sep 17 00:00:00 2001
From: Him188 <Him188@mamoe.net>
Date: Thu, 30 Jan 2020 23:53:28 +0800
Subject: [PATCH] Improve login and init

---
 .../network/QQAndroidBotNetworkHandler.kt     | 127 +++++++++---------
 .../kotlin/net.mamoe.mirai/BotImpl.kt         |  21 ++-
 .../network/BotNetworkHandler.kt              |   7 +
 3 files changed, 85 insertions(+), 70 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 8bb5551f5..609f157c7 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
@@ -37,84 +37,79 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
 
 
     override suspend fun login() {
-        suspend fun doLogin() {
-            channel = PlatformSocket()
-            channel.connect("113.96.13.208", 8080)
-            launch(CoroutineName("Incoming Packet Receiver")) { processReceive() }
+        channel = PlatformSocket()
+        channel.connect("113.96.13.208", 8080)
+        launch(CoroutineName("Incoming Packet Receiver")) { processReceive() }
 
-            bot.logger.info("Trying login")
-            var response: LoginPacket.LoginPacketResponse = LoginPacket.SubCommand9(bot.client).sendAndExpect()
-            mainloop@ while (true) {
-                when (response) {
-                    is LoginPacket.LoginPacketResponse.UnsafeLogin -> {
-                        bot.configuration.loginSolver.onSolveUnsafeDeviceLoginVerify(bot, response.url)
-                        response = LoginPacket.SubCommand9(bot.client).sendAndExpect()
-                    }
+        bot.logger.info("Trying login")
+        var response: LoginPacket.LoginPacketResponse = LoginPacket.SubCommand9(bot.client).sendAndExpect()
+        mainloop@ while (true) {
+            when (response) {
+                is LoginPacket.LoginPacketResponse.UnsafeLogin -> {
+                    bot.configuration.loginSolver.onSolveUnsafeDeviceLoginVerify(bot, response.url)
+                    response = LoginPacket.SubCommand9(bot.client).sendAndExpect()
+                }
 
-                    is LoginPacket.LoginPacketResponse.Captcha -> when (response) {
-                        is LoginPacket.LoginPacketResponse.Captcha.Picture -> {
-                            var result = response.data.withUse {
-                                bot.configuration.loginSolver.onSolvePicCaptcha(bot, this)
-                            }
-                            if (result == null || result.length != 4) {
-                                //refresh captcha
-                                result = "ABCD"
-                            }
-                            response = LoginPacket.SubCommand2.SubmitPictureCaptcha(bot.client, response.sign, result).sendAndExpect()
-                            continue@mainloop
+                is LoginPacket.LoginPacketResponse.Captcha -> when (response) {
+                    is LoginPacket.LoginPacketResponse.Captcha.Picture -> {
+                        var result = response.data.withUse {
+                            bot.configuration.loginSolver.onSolvePicCaptcha(bot, this)
                         }
-                        is LoginPacket.LoginPacketResponse.Captcha.Slider -> {
-                            var ticket = bot.configuration.loginSolver.onSolveSliderCaptcha(bot, response.url)
-                            if (ticket == null) {
-                                ticket = ""
-                            }
-                            response = LoginPacket.SubCommand2.SubmitSliderCaptcha(bot.client, ticket).sendAndExpect()
-                            continue@mainloop
+                        if (result == null || result.length != 4) {
+                            //refresh captcha
+                            result = "ABCD"
                         }
-                    }
-
-                    is LoginPacket.LoginPacketResponse.Error -> error(response.toString())
-
-                    is LoginPacket.LoginPacketResponse.DeviceLockLogin -> {
-                        response = LoginPacket.SubCommand20(
-                            bot.client,
-                            response.t402,
-                            response.t403
-                        ).sendAndExpect()
+                        response = LoginPacket.SubCommand2.SubmitPictureCaptcha(bot.client, response.sign, result).sendAndExpect()
                         continue@mainloop
                     }
-
-                    is LoginPacket.LoginPacketResponse.Success -> {
-                        bot.logger.info("Login successful")
-                        break@mainloop
+                    is LoginPacket.LoginPacketResponse.Captcha.Slider -> {
+                        var ticket = bot.configuration.loginSolver.onSolveSliderCaptcha(bot, response.url)
+                        if (ticket == null) {
+                            ticket = ""
+                        }
+                        response = LoginPacket.SubCommand2.SubmitSliderCaptcha(bot.client, ticket).sendAndExpect()
+                        continue@mainloop
                     }
                 }
+
+                is LoginPacket.LoginPacketResponse.Error -> error(response.toString())
+
+                is LoginPacket.LoginPacketResponse.DeviceLockLogin -> {
+                    response = LoginPacket.SubCommand20(
+                        bot.client,
+                        response.t402,
+                        response.t403
+                    ).sendAndExpect()
+                    continue@mainloop
+                }
+
+                is LoginPacket.LoginPacketResponse.Success -> {
+                    bot.logger.info("Login successful")
+                    break@mainloop
+                }
             }
-
-            println("d2key=${bot.client.wLoginSigInfo.d2Key.toUHexString()}")
-            StatSvc.Register(bot.client).sendAndExpect<StatSvc.Register.Response>()
         }
 
-        suspend fun doInit() {
-            //start updating friend/group list
-            bot.logger.info("Start updating friend/group list")
-            /*
-            val data = FriendList.GetFriendGroupList(
-                bot.client,
-                0,
-                1,
-                0,
-                2
-            ).sendAndExpect<FriendList.GetFriendGroupList.Response>()
-             */
-            val data = FriendList.GetTroopList(
-                bot.client
-            ).sendAndExpect<FriendList.GetFriendGroupList.Response>()
-            println(data.contentToString())
-        }
+        println("d2key=${bot.client.wLoginSigInfo.d2Key.toUHexString()}")
+        StatSvc.Register(bot.client).sendAndExpect<StatSvc.Register.Response>()
+    }
 
-        doLogin()
-        doInit()
+    suspend fun init() {
+        //start updating friend/group list
+        bot.logger.info("Start updating friend/group list")
+        /*
+        val data = FriendList.GetFriendGroupList(
+            bot.client,
+            0,
+            1,
+            0,
+            2
+        ).sendAndExpect<FriendList.GetFriendGroupList.Response>()
+         */
+        val data = FriendList.GetTroopList(
+            bot.client
+        ).sendAndExpect<FriendList.GetFriendGroupList.Response>()
+        println(data.contentToString())
     }
 
 
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
index 1a8d8d063..6a6293f31 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
@@ -27,7 +27,8 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
     @Suppress("CanBePrimaryConstructorProperty") // for logger
     final override val account: BotAccount = account
     @UseExperimental(RawAccountIdUse::class)
-    override val uin: Long get() = account.id
+    override val uin: Long
+        get() = account.id
     final override val logger: MiraiLogger by lazy { configuration.logger ?: DefaultLogger("Bot($uin)").also { configuration.logger = it } }
 
     init {
@@ -98,16 +99,28 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
         }
         _network = createNetworkHandler(this.coroutineContext)
 
-        while (true){
+        loginLoop@ while (true) {
             try {
-                return _network.login()
-            } catch (e: Exception){
+                _network.login()
+                break@loginLoop
+            } catch (e: Exception) {
                 e.logStacktrace()
                 _network.dispose(e)
             }
             logger.warning("Login failed. Retrying in 3s...")
             delay(3000)
         }
+
+        while (true) {
+            try {
+                return _network.init()
+            } catch (e: Exception) {
+                e.logStacktrace()
+                _network.dispose(e)
+            }
+            logger.warning("Init failed. Retrying in 3s...")
+            delay(3000)
+        }
     }
 
     protected abstract fun createNetworkHandler(coroutineContext: CoroutineContext): N
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 4341880a9..f1ff2c865 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
@@ -47,6 +47,13 @@ abstract class BotNetworkHandler : CoroutineScope {
     @MiraiInternalAPI
     abstract suspend fun login()
 
+    /**
+     * 初始化获取好友列表等值.
+     */
+    @MiraiInternalAPI
+    open suspend fun init() {
+    }
+
     /**
      * 等待直到与服务器断开连接. 若未连接则立即返回
      */