Fix fast login

This commit is contained in:
Karlatemp 2021-06-19 02:30:06 +08:00
parent 04656d7a03
commit 77e5e91fc4
No known key found for this signature in database
GPG Key ID: 21FBDDF664FF06F8
3 changed files with 36 additions and 2 deletions

View File

@ -9,6 +9,7 @@
package net.mamoe.mirai.internal.network.components
import kotlinx.coroutines.delay
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.QQAndroidClient
@ -17,7 +18,9 @@ import net.mamoe.mirai.internal.network.context.AccountSecretsImpl
import net.mamoe.mirai.internal.network.context.SsoProcessorContext
import net.mamoe.mirai.internal.network.context.SsoSession
import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException
import net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandler
import net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketWithRespType
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin.Login.LoginPacketResponse
@ -42,6 +45,7 @@ internal interface SsoProcessor {
var firstLoginSucceed: Boolean
val registerResp: StatSvc.Register.Response?
val runningFastLogin: Boolean
/**
* Do login. Throws [LoginFailedException] if failed
@ -77,6 +81,9 @@ internal class SsoProcessorImpl(
@Volatile
override var registerResp: StatSvc.Register.Response? = null
@Volatile
override var runningFastLogin: Boolean = false
override var client
get() = ssoContext.bot.components[BotClientHolder].client
set(value) {
@ -94,8 +101,11 @@ internal class SsoProcessorImpl(
components[BdhSessionSyncer].loadServerListFromCache()
if (client.wLoginSigInfoInitialized) {
kotlin.runCatching {
runningFastLogin = true
FastLoginImpl(handler).doLogin()
runningFastLogin = false
}.onFailure { e ->
runningFastLogin = false
collectException(e)
SlowLoginImpl(handler).doLogin()
}
@ -265,8 +275,28 @@ internal class SsoProcessorImpl(
private inner class FastLoginImpl(handler: NetworkHandler) : LoginStrategy(handler) {
override suspend fun doLogin() {
val login10 = WtLogin10(client).sendAndExpect(handler)
check(login10 is LoginPacketResponse.Success) { "Fast login failed: $login10" }
var offline: RequestPushForceOffline? = null
val listener = components[PacketInterceptor].registerTemporaryInterceptor { context, incomingPacket ->
if (incomingPacket.data is RequestPushForceOffline) {
offline = incomingPacket.data
}
if (offline != null) {
context.finished()
}
}
try {
val login10 = WtLogin10(client).sendAndExpect(handler)
check(login10 is LoginPacketResponse.Success) { "Fast login failed: $login10" }
delay(3000) // wait MessageSvc.PushForceOffline
listener.unregister()
if (offline != null) {
throw ForceOfflineException(offline!!.title, "Closed by MessageSvc.PushForceOffline: ${offline?.tips}")
}
} finally {
listener.unregister()
}
}
}
}

View File

@ -12,6 +12,7 @@ package net.mamoe.mirai.internal.network.protocol.packet.chat.receive
import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.components.AccountSecretsManager
import net.mamoe.mirai.internal.network.components.SsoProcessor
import net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException
import net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketFactory
@ -30,6 +31,7 @@ internal object MessageSvcPushForceOffline :
override suspend fun QQAndroidBot.handle(packet: RequestPushForceOffline) {
components[AccountSecretsManager].invalidate() // otherwise you receive `MessageSvc.PushForceOffline` again just after logging in.
if (components[SsoProcessor].runningFastLogin) return
network.close(ForceOfflineException(packet.title, "Closed by MessageSvc.PushForceOffline: $packet"))
}
}

View File

@ -30,6 +30,8 @@ internal open class TestSsoProcessor(private val bot: QQAndroidBot) : SsoProcess
override val ssoSession: SsoSession get() = bot.client
override var firstLoginSucceed: Boolean = false
override var registerResp: StatSvc.Register.Response? = null
override val runningFastLogin: Boolean
get() = false
override suspend fun login(handler: NetworkHandler) {
firstLoginSucceed = true
bot.network.logger.debug { "SsoProcessor.login" }