Renew QQAndroidClient on reconnection

This commit is contained in:
Him188 2021-01-25 21:44:24 +08:00
parent af9eadf34e
commit d3b9741bdb
3 changed files with 23 additions and 10 deletions

View File

@ -49,16 +49,20 @@ internal fun QQAndroidBot.createOtherClient(
@Suppress("INVISIBLE_MEMBER", "BooleanLiteralArgument", "OverridingDeprecatedMember") @Suppress("INVISIBLE_MEMBER", "BooleanLiteralArgument", "OverridingDeprecatedMember")
internal class QQAndroidBot constructor( internal class QQAndroidBot constructor(
account: BotAccount, private val account: BotAccount,
configuration: BotConfiguration configuration: BotConfiguration
) : AbstractBot<QQAndroidBotNetworkHandler>(configuration, account.id) { ) : AbstractBot<QQAndroidBotNetworkHandler>(configuration, account.id) {
@Suppress("LeakingThis") var client: QQAndroidClient = initClient()
val client: QQAndroidClient =
QQAndroidClient( fun initClient(): QQAndroidClient {
client = QQAndroidClient(
account, account,
bot = this, bot = this,
device = configuration.deviceInfo?.invoke(this) ?: DeviceInfo.random() device = configuration.deviceInfo?.invoke(this) ?: DeviceInfo.random()
) )
return client
}
internal var firstLoginSucceed: Boolean = false internal var firstLoginSucceed: Boolean = false
inline val json get() = configuration.json inline val json get() = configuration.json

View File

@ -82,7 +82,6 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
private suspend fun startPacketReceiverJobOrKill(cancelCause: CancellationException? = null): Job { private suspend fun startPacketReceiverJobOrKill(cancelCause: CancellationException? = null): Job {
_packetReceiverJob?.cancel(cancelCause) _packetReceiverJob?.cancel(cancelCause)
_packetReceiverJob?.join()
return this.launch(CoroutineName("Incoming Packet Receiver")) { return this.launch(CoroutineName("Incoming Packet Receiver")) {
while (channel.isOpen && isActive) { while (channel.isOpen && isActive) {
@ -91,6 +90,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
} catch (e: CancellationException) { } catch (e: CancellationException) {
return@launch return@launch
} catch (e: Throwable) { } catch (e: Throwable) {
logger.warning { "Channel closed." }
if (this@QQAndroidBotNetworkHandler.isActive) { if (this@QQAndroidBotNetworkHandler.isActive) {
bot.launch { BotOfflineEvent.Dropped(bot, e).broadcast() } bot.launch { BotOfflineEvent.Dropped(bot, e).broadcast() }
} }
@ -139,7 +139,9 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
// } // }
channel.close() channel.close()
} }
channel = PlatformSocket() channel = PlatformSocket()
bot.initClient()
while (isActive) { while (isActive) {
try { try {
@ -570,6 +572,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
*/ */
@Throws(ForceOfflineException::class) @Throws(ForceOfflineException::class)
suspend fun parsePacket(input: ByteReadPacket) { suspend fun parsePacket(input: ByteReadPacket) {
if (input.isEmpty) return
generifiedParsePacket<Packet>(input) generifiedParsePacket<Packet>(input)
} }
@ -662,6 +665,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
if (rawInput.remaining == 0L) { if (rawInput.remaining == 0L) {
cachedPacket.value = null // 表示包长度正好 cachedPacket.value = null // 表示包长度正好
cachedPacketTimeoutJob?.cancel() cachedPacketTimeoutJob?.cancel()
rawInput.close()
return return
} }
length = rawInput.readInt() - 4 length = rawInput.readInt() - 4
@ -674,6 +678,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
} else { } else {
cachedPacket.value = null // 表示包长度正好 cachedPacket.value = null // 表示包长度正好
cachedPacketTimeoutJob?.cancel() cachedPacketTimeoutJob?.cancel()
rawInput.close()
return return
} }
}.getOrElse { }.getOrElse {
@ -689,12 +694,15 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
writePacket(cache) writePacket(cache)
writePacket(rawInput, expectingLength) writePacket(rawInput, expectingLength)
}) })
cache.close()
cachedPacket.value = null // 缺少的长度已经给上了. cachedPacket.value = null // 缺少的长度已经给上了.
cachedPacketTimeoutJob?.cancel() cachedPacketTimeoutJob?.cancel()
if (rawInput.remaining != 0L) { if (rawInput.remaining != 0L) {
return processPacket(rawInput) // 继续处理剩下内容 return processPacket(rawInput) // 继续处理剩下内容
} else { } else {
rawInput.close()
// 处理好了. // 处理好了.
return return
} }
@ -713,8 +721,10 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
cachedPacketTimeoutJob?.cancel() cachedPacketTimeoutJob?.cancel()
cachedPacketTimeoutJob = launch { cachedPacketTimeoutJob = launch {
delay(1000) delay(1000)
if (cachedPacketTimeoutJob == this.coroutineContext[Job] && cachedPacket.getAndSet(null) != null) { val get = cachedPacket.getAndSet(null)
PacketLogger.verbose { "等待另一部分包时超时. 将舍弃已接收的半个包" } get?.close()
if (cachedPacketTimeoutJob == this.coroutineContext[Job] && get != null) {
logger.warning { "等待另一部分包时超时. 将舍弃已接收的半个包" }
} }
} }
} }
@ -759,7 +769,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
return retryCatchingExceptions( return retryCatchingExceptions(
retry + 1, retry + 1,
except = CancellationException::class // CancellationException means network closed so don't retry except = CancellationException::class.cast() // CancellationException means network closed so don't retry
) { ) {
withPacketListener(commandName, sequenceId) { listener -> withPacketListener(commandName, sequenceId) { listener ->
return withTimeout(timeoutMillis) { // may throw CancellationException return withTimeout(timeoutMillis) { // may throw CancellationException

View File

@ -118,8 +118,7 @@ internal open class QQAndroidClient(
val bot: QQAndroidBot by bot.unsafeWeakRef() val bot: QQAndroidBot by bot.unsafeWeakRef()
internal var tgtgtKey: ByteArray = generateTgtgtKey(device.guid) internal var tgtgtKey: ByteArray = generateTgtgtKey(device.guid)
internal val randomKey: ByteArray = getRandomByteArray(16) internal var randomKey: ByteArray = getRandomByteArray(16)
internal val miscBitMap: Int = protocol.miscBitMap // 184024956 // 也可能是 150470524 ? internal val miscBitMap: Int = protocol.miscBitMap // 184024956 // 也可能是 150470524 ?
internal val mainSigMap: Int = protocol.mainSigMap internal val mainSigMap: Int = protocol.mainSigMap