1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-03-02 14:30:13 +08:00

Merge remote-tracking branch 'origin/master'

This commit is contained in:
jiahua.liu 2020-02-08 14:51:57 +08:00
commit b99725853f
6 changed files with 97 additions and 6 deletions
mirai-core-qqandroid/src
commonMain/kotlin/net/mamoe/mirai/qqandroid/network
jvmTest/kotlin/test
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils

View File

@ -243,6 +243,28 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
bot.logger.info("====================Mirai Bot List初始化完毕====================")
bot.firstLoginSucceed = true
launch {
while (this.isActive) {
delay(bot.configuration.heartbeatPeriodMillis)
var lastException: Exception?
try {
check(
StatSvc.GetOnlineStatus(bot.client)
.sendAndExpect<StatSvc.GetOnlineStatus.Response>(
timeoutMillis = bot.configuration.heartbeatTimeoutMillis,
retry = 1
) is StatSvc.GetOnlineStatus.Response.Success
)
continue
} catch (e: Exception) {
lastException = e
}
delay(bot.configuration.firstReconnectDelayMillis)
close()
bot.tryReinitializeNetworkHandler(lastException)
}
}
}

View File

@ -0,0 +1,29 @@
package net.mamoe.mirai.qqandroid.network.protocol.data.proto
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable
import net.mamoe.mirai.qqandroid.io.ProtoBuf
class StatSvcGetOnline {
@Serializable
class Instance(
@SerialId(1) val instanceId: Int = 0,
@SerialId(2) val clientType: Int = 0
) : ProtoBuf
@Serializable
class ReqBody(
@SerialId(1) val uin: Long = 0L,
@SerialId(2) val appid: Int = 0
) : ProtoBuf
@Serializable
class RspBody(
@SerialId(1) val errorCode: Int = 0,
@SerialId(2) val errorMsg: String = "",
@SerialId(3) val uin: Long = 0L,
@SerialId(4) val appid: Int = 0,
@SerialId(5) val timeInterval: Int = 0,
@SerialId(6) val msgInstances: List<StatSvcGetOnline.Instance>? = null
) : ProtoBuf
}

View File

@ -112,6 +112,7 @@ internal object KnownPacketFactories {
object OutgoingFactories : List<OutgoingPacketFactory<*>> by mutableListOf(
LoginPacket,
StatSvc.Register,
StatSvc.GetOnlineStatus,
MessageSvc.PbGetMsg,
MessageSvc.PushForceOffline,
MessageSvc.PbSendMsg,

View File

@ -3,12 +3,11 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.login
import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import net.mamoe.mirai.qqandroid.io.serialization.jceRequestSBuffer
import net.mamoe.mirai.qqandroid.io.serialization.writeJceStruct
import net.mamoe.mirai.qqandroid.io.serialization.*
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.SvcReqRegister
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.StatSvcGetOnline
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildLoginOutgoingPacket
@ -33,6 +32,46 @@ internal enum class RegPushReason {
}
internal class StatSvc {
internal object GetOnlineStatus : OutgoingPacketFactory<GetOnlineStatus.Response>("StatSvc.GetOnlineStatus") {
internal sealed class Response : Packet {
override fun toString(): String = "StatSvc.GetOnlineStatus.Response"
object Success : Response() {
override fun toString(): String {
return "StatSvc.GetOnlineStatus.Response.Success"
}
}
class Failed(val errno: Int, val message: String) : Response() {
override fun toString(): String {
return "StatSvc.GetOnlineStatus.Response.Failed(errno=$errno, message=$message)"
}
}
}
operator fun invoke(
client: QQAndroidClient
): OutgoingPacket = buildLoginOutgoingPacket(client, 1) {
writeProtoBuf(
StatSvcGetOnline.ReqBody.serializer(), StatSvcGetOnline.ReqBody(
uin = client.uin,
appid = 0
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
val resp = readProtoBuf(StatSvcGetOnline.RspBody.serializer())
return if (resp.errorCode != 0) {
Response.Failed(resp.errorCode, resp.errorMsg)
} else {
Response.Success
}
}
}
internal object Register : OutgoingPacketFactory<Register.Response>("StatSvc.register") {
internal object Response : Packet {

View File

@ -16,7 +16,7 @@ fun main() {
println(
File(
"""
/Users/jiahua.liu/Desktop/QQAndroid-F/app/src/main/java/tencent/im/oidb/cmd0x8a0/
E:\Projects\QQAndroidFF\app\src\main\java\tencent\im\statsvc\getonline
""".trimIndent()
)
.generateUnarrangedClasses().toMutableList().arrangeClasses().joinToString("\n\n")

View File

@ -49,10 +49,10 @@ class BotConfiguration {
/**
* 心跳周期. 过长会导致被服务器断开连接.
*/
var heartbeatPeriodMillis: Long = 60.secondsToMillis
var heartbeatPeriodMillis: Long = 30.secondsToMillis
/**
* 每次心跳时等待结果的时间.
* 一旦心跳超时, 整个网络服务将会重启 (将消耗约 1s). 除正在进行的任务 (如图片上传) 会被中断外, 事件和插件均不受影响.
* 一旦心跳超时, 整个网络服务将会重启 (将消耗约 5s). 除正在进行的任务 (如图片上传) 会被中断外, 事件和插件均不受影响.
*/
var heartbeatTimeoutMillis: Long = 2.secondsToMillis
/**