Move network stuffs into mirai-core

This commit is contained in:
Him188 2019-12-24 00:33:23 +08:00
parent 9534723ff7
commit 33ab0c820e
8 changed files with 177 additions and 57 deletions

View File

@ -0,0 +1,13 @@
package net.mamoe.mirai.qqandroid
import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.utils.MiraiLogger
import kotlin.coroutines.CoroutineContext
internal actual class QQAndroidBot actual constructor(
account: BotAccount,
logger: MiraiLogger?,
context: CoroutineContext
) : QQAndroidBotBase(account, logger, context) {
}

View File

@ -0,0 +1,68 @@
package net.mamoe.mirai.qqandroid
import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.BotImpl
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.AddFriendResult
import net.mamoe.mirai.data.ImageLink
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler
import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.MiraiLogger
import kotlin.coroutines.CoroutineContext
internal expect class QQAndroidBot(
account: BotAccount,
logger: MiraiLogger?,
context: CoroutineContext
) : QQAndroidBotBase
@UseExperimental(MiraiInternalAPI::class)
internal abstract class QQAndroidBotBase constructor(
account: BotAccount,
logger: MiraiLogger?,
context: CoroutineContext
) : BotImpl<QQAndroidBotNetworkHandler>(account, logger, context) {
override val qqs: ContactList<QQ>
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
override fun getQQ(id: Long): QQ {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun createNetworkHandler(coroutineContext: CoroutineContext): QQAndroidBotNetworkHandler {
return QQAndroidBotNetworkHandler(this as QQAndroidBot)
}
override val groups: ContactList<Group>
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
override suspend fun getGroup(id: GroupId): Group {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override suspend fun getGroup(internalId: GroupInternalId): Group {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override suspend fun getGroup(id: Long): Group {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override suspend fun login(configuration: BotConfiguration) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override suspend fun Image.getLink(): ImageLink {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override suspend fun addFriend(id: Long, message: String?, remark: String?): AddFriendResult {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override suspend fun approveFriendAddRequest(id: Long, remark: String?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}

View File

@ -0,0 +1,22 @@
package net.mamoe.mirai.qqandroid.network
import kotlinx.coroutines.CompletableJob
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.qqandroid.QQAndroidBot
import kotlin.coroutines.CoroutineContext
internal class QQAndroidBotNetworkHandler(override val bot: QQAndroidBot) : BotNetworkHandler() {
override val supervisor: CompletableJob = SupervisorJob(bot.coroutineContext[Job])
override suspend fun login() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override suspend fun awaitDisconnection() {
TODO()
}
override val coroutineContext: CoroutineContext = bot.coroutineContext
}

View File

@ -0,0 +1,18 @@
package net.mamoe.mirai.qqandroid
import kotlinx.coroutines.GlobalScope
import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.alsoLogin
import net.mamoe.mirai.utils.MiraiLogger
import kotlin.coroutines.CoroutineContext
internal actual class QQAndroidBot actual constructor(
account: BotAccount,
logger: MiraiLogger?,
context: CoroutineContext
) : QQAndroidBotBase(account, logger, context)
suspend fun main() {
val bot = QQAndroidBot(BotAccount(1, ""), null, GlobalScope.coroutineContext).alsoLogin()
bot.network.awaitDisconnection()
}

View File

@ -19,7 +19,7 @@ import net.mamoe.mirai.timpc.internal.RawGroupInfo
import net.mamoe.mirai.timpc.network.GroupImpl
import net.mamoe.mirai.timpc.network.MemberImpl
import net.mamoe.mirai.timpc.network.QQImpl
import net.mamoe.mirai.timpc.network.TIMBotNetworkHandler
import net.mamoe.mirai.timpc.network.TIMPCBotNetworkHandler
import net.mamoe.mirai.timpc.network.handler.TemporaryPacketHandler
import net.mamoe.mirai.timpc.network.packet.action.*
import net.mamoe.mirai.timpc.network.packet.event.EventPacketFactory
@ -46,7 +46,7 @@ internal abstract class TIMPCBotBase constructor(
account: BotAccount,
logger: MiraiLogger?,
context: CoroutineContext
) : BotImpl<TIMBotNetworkHandler>(account, logger ?: DefaultLogger("Bot(" + account.id + ")"), context) {
) : BotImpl<TIMPCBotNetworkHandler>(account, logger ?: DefaultLogger("Bot(" + account.id + ")"), context) {
@UseExperimental(ExperimentalUnsignedTypes::class)
companion object {
@ -85,47 +85,10 @@ internal abstract class TIMPCBotBase constructor(
}
}
final override val network: TIMBotNetworkHandler get() = _network
inline val sessionKey: SessionKey get()= network.sessionKey
inline val sessionKey: SessionKey get() = network.sessionKey
private lateinit var _network: TIMBotNetworkHandler
override suspend fun login(configuration: BotConfiguration) =
reinitializeNetworkHandler(configuration, null)
// shouldn't be suspend!! This function MUST NOT inherit the context from the caller because the caller(NetworkHandler) is going to close
internal fun tryReinitializeNetworkHandler(
configuration: BotConfiguration,
cause: Throwable?
): Job = launch {
repeat(configuration.reconnectionRetryTimes) {
try {
reinitializeNetworkHandler(configuration, cause)
logger.info("Reconnected successfully")
return@launch
} catch (e: LoginFailedException) {
delay(configuration.reconnectPeriodMillis)
}
}
}
private suspend fun reinitializeNetworkHandler(
configuration: BotConfiguration,
cause: Throwable?
) {
logger.info("BotAccount: $qqAccount")
logger.info("Initializing BotNetworkHandler")
try {
if (::_network.isInitialized) {
_network.close(cause)
}
} catch (e: Exception) {
logger.error("Cannot close network handler", e)
}
_network = TIMBotNetworkHandler(this.coroutineContext + configuration, this as TIMPCBot)
_network.login()
override fun createNetworkHandler(coroutineContext: CoroutineContext): TIMPCBotNetworkHandler {
return TIMPCBotNetworkHandler(coroutineContext, this as TIMPCBot)
}
final override suspend fun addFriend(id: Long, message: String?, remark: String?): AddFriendResult {

View File

@ -37,7 +37,7 @@ internal expect val NetworkDispatcher: CoroutineDispatcher
*
* @see BotNetworkHandler
*/
internal class TIMBotNetworkHandler internal constructor(coroutineContext: CoroutineContext, bot: TIMPCBot) :
internal class TIMPCBotNetworkHandler internal constructor(coroutineContext: CoroutineContext, bot: TIMPCBot) :
BotNetworkHandler(), CoroutineScope {
override val bot: TIMPCBot by bot.unsafeWeakRef()
override val supervisor: CompletableJob = SupervisorJob(coroutineContext[Job])
@ -160,7 +160,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
with(id.factory) {
loginHandler!!.provideDecrypter(id.factory)
.decrypt(input)
.decode(id, sequenceId, this@TIMBotNetworkHandler)
.decode(id, sequenceId, this@TIMPCBotNetworkHandler)
}
} finally {
input.close()
@ -272,7 +272,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
Unit
}
override val owner: Bot get() = this@TIMBotNetworkHandler.bot
override val owner: Bot get() = this@TIMPCBotNetworkHandler.bot
override fun close() {
loginHandler?.close()
@ -452,7 +452,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
BotLoginSucceedEvent(bot).broadcast()
val configuration = currentBotConfiguration()
heartbeatJob = this@TIMBotNetworkHandler.launch {
heartbeatJob = this@TIMPCBotNetworkHandler.launch {
while (socket.isOpen) {
delay(configuration.heartbeatPeriodMillis)
with(bot) {

View File

@ -7,7 +7,7 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.timpc.network.TIMBotNetworkHandler
import net.mamoe.mirai.timpc.network.TIMPCBotNetworkHandler
import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket
import net.mamoe.mirai.utils.io.readIoBuffer
@ -46,7 +46,7 @@ internal object EventPacketFactory : PacketFactory<Packet, SessionKey>(SessionKe
to = readUInt().toLong(), // clear semantic
uniqueId = readIoBuffer(8)
)
(handler as TIMBotNetworkHandler).socket.sendPacket(EventPacketFactory(id, sequenceId, handler.bot.qqAccount, handler.sessionKey, eventIdentity))
(handler as TIMPCBotNetworkHandler).socket.sendPacket(EventPacketFactory(id, sequenceId, handler.bot.qqAccount, handler.sessionKey, eventIdentity))
discardExact(2) // 1F 40
return with(matchEventPacketFactory(readUShort())) { parse(handler.bot, eventIdentity) }.also {

View File

@ -2,15 +2,9 @@
package net.mamoe.mirai
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.*
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.LockFreeLinkedList
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.logStacktrace
import kotlin.coroutines.CoroutineContext
@ -56,7 +50,49 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
// region network
abstract override val network: N
final override val network: N get() = _network
private lateinit var _network: N
override suspend fun login(configuration: BotConfiguration) =
reinitializeNetworkHandler(configuration, null)
// shouldn't be suspend!! This function MUST NOT inherit the context from the caller because the caller(NetworkHandler) is going to close
fun tryReinitializeNetworkHandler(
configuration: BotConfiguration,
cause: Throwable?
): Job = launch {
repeat(configuration.reconnectionRetryTimes) {
try {
reinitializeNetworkHandler(configuration, cause)
logger.info("Reconnected successfully")
return@launch
} catch (e: LoginFailedException) {
delay(configuration.reconnectPeriodMillis)
}
}
}
private suspend fun reinitializeNetworkHandler(
configuration: BotConfiguration,
cause: Throwable?
) {
logger.info("BotAccount: $qqAccount")
logger.info("Initializing BotNetworkHandler")
try {
if (::_network.isInitialized) {
_network.close(cause)
}
} catch (e: Exception) {
logger.error("Cannot close network handler", e)
}
_network = createNetworkHandler(this.coroutineContext + configuration)
_network.login()
}
protected abstract fun createNetworkHandler(coroutineContext: CoroutineContext): N
// endregion
@UseExperimental(MiraiInternalAPI::class)