mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-08 17:20:11 +08:00
Remove PacketHandler
This commit is contained in:
parent
afd87826b8
commit
76e6e37c38
@ -5,9 +5,8 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.BotSocketAdapter
|
||||
import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.LoginHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.*
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.DataPacketSocketAdapter
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.TemporaryPacketHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.Packet
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.HeartbeatPacket
|
||||
@ -18,16 +17,7 @@ import net.mamoe.mirai.utils.io.PlatformDatagramChannel
|
||||
|
||||
/**
|
||||
* Mirai 的网络处理器, 它承担所有数据包([Packet])的处理任务.
|
||||
* [BotNetworkHandler] 是全异步和线程安全的.
|
||||
*
|
||||
* [BotNetworkHandler] 由 2 个模块构成:
|
||||
* - [BotSocketAdapter]: 处理数据包底层的发送([ByteArray])
|
||||
* - [PacketHandler]: 制作 [OutgoingPacket] 并传递给 [BotSocketAdapter] 发送; 分析 [Packet] 并处理
|
||||
*
|
||||
* 其中, [PacketHandler] 由 3 个子模块构成:
|
||||
* - [LoginHandler] 处理 sendTouch/login/verification code 相关
|
||||
* - [ActionPacketHandler] 处理动作相关(踢人/加入群/好友列表等)
|
||||
*
|
||||
* [BotNetworkHandler] 是线程安全的.
|
||||
*
|
||||
* NetworkHandler 实现接口 [CoroutineScope]
|
||||
* 即 [BotNetworkHandler] 自己就是作用域.
|
||||
@ -50,14 +40,7 @@ interface BotNetworkHandler<Socket : DataPacketSocketAdapter> : CoroutineScope {
|
||||
|
||||
val supervisor get() = SupervisorJob()
|
||||
|
||||
/**
|
||||
* 得到 [PacketHandler].
|
||||
* `get(EventPacketHandler)` 返回 [EventPacketHandler]
|
||||
* `get(ActionPacketHandler)` 返回 [ActionPacketHandler].
|
||||
*
|
||||
* 这个方法在 [PacketHandlerList] 中实现
|
||||
*/
|
||||
operator fun <T : PacketHandler> get(key: PacketHandler.Key<T>): T
|
||||
val session: BotSession
|
||||
|
||||
/**
|
||||
* 依次尝试登录到可用的服务器. 在任一服务器登录完成后返回登录结果
|
||||
|
@ -15,7 +15,6 @@ import net.mamoe.mirai.message.Image
|
||||
import net.mamoe.mirai.message.ImageId0x03
|
||||
import net.mamoe.mirai.message.ImageId0x06
|
||||
import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.ActionPacketHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.DataPacketSocketAdapter
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.TemporaryPacketHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
|
||||
@ -65,29 +64,29 @@ abstract class BotSessionBase(
|
||||
val socket: DataPacketSocketAdapter,
|
||||
val NetworkScope: CoroutineScope
|
||||
) {
|
||||
|
||||
/**
|
||||
* Web api 使用
|
||||
*/
|
||||
lateinit var cookies: String
|
||||
val cookies: String get() = _cookies
|
||||
|
||||
/**
|
||||
* Web api 使用
|
||||
*/
|
||||
val sKey: String get() = _sKey
|
||||
|
||||
/**
|
||||
* Web api 使用
|
||||
*/
|
||||
val gtk: Int get() = _gtk
|
||||
|
||||
|
||||
@Suppress("PropertyName")
|
||||
internal var _sKey: String = ""
|
||||
set(value) {
|
||||
field = value
|
||||
_gtk = getGTK(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Web api 使用
|
||||
*/
|
||||
val gtk: Int get() = _gtk
|
||||
|
||||
internal lateinit var _cookies: String
|
||||
private var _gtk: Int = 0
|
||||
|
||||
/**
|
||||
@ -163,12 +162,6 @@ abstract class BotSessionBase(
|
||||
inline val BotSession.isOpen: Boolean get() = socket.isOpen
|
||||
inline val BotSession.qqAccount: UInt get() = bot.account.id
|
||||
|
||||
/**
|
||||
* 取得 [BotNetworkHandler] 的 [BotSession].
|
||||
* 实际上是一个捷径.
|
||||
*/
|
||||
val BotNetworkHandler<*>.session: BotSession get() = this[ActionPacketHandler].session
|
||||
|
||||
/**
|
||||
* 取得 [BotNetworkHandler] 的 sessionKey.
|
||||
* 实际上是一个捷径.
|
||||
|
@ -15,10 +15,10 @@ import net.mamoe.mirai.event.events.PacketSentEvent
|
||||
import net.mamoe.mirai.event.events.ServerPacketReceivedEvent
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.network.BotSession
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.*
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.DataPacketSocketAdapter
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.TemporaryPacketHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.*
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.*
|
||||
import net.mamoe.mirai.network.session
|
||||
import net.mamoe.mirai.qqAccount
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.OnlineStatus
|
||||
@ -40,7 +40,7 @@ internal expect val NetworkDispatcher: CoroutineDispatcher
|
||||
* @see BotNetworkHandler
|
||||
*/
|
||||
internal class TIMBotNetworkHandler internal constructor(coroutineContext: CoroutineContext, override inline val bot: Bot) :
|
||||
BotNetworkHandler<TIMBotNetworkHandler.BotSocketAdapter>, PacketHandlerList(), CoroutineScope {
|
||||
BotNetworkHandler<TIMBotNetworkHandler.BotSocketAdapter>, CoroutineScope {
|
||||
|
||||
|
||||
override val coroutineContext: CoroutineContext =
|
||||
@ -94,13 +94,11 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
|
||||
internal var loginResult: CompletableDeferred<LoginResult> = CompletableDeferred()
|
||||
|
||||
override lateinit var session: BotSession
|
||||
|
||||
//private | internal
|
||||
private fun onLoggedIn() {
|
||||
require(size == 0) { "Already logged in" }
|
||||
val session = BotSession(sessionKey, socket)
|
||||
|
||||
add(ActionPacketHandler(session).asNode(ActionPacketHandler))
|
||||
session = BotSession(sessionKey, socket)
|
||||
bot.logger.info("Successfully logged in")
|
||||
}
|
||||
|
||||
@ -122,10 +120,6 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
this.loginResult.join()
|
||||
}
|
||||
|
||||
this.forEach {
|
||||
it.instance.close()
|
||||
}
|
||||
|
||||
this.socket.close()
|
||||
}
|
||||
|
||||
@ -138,7 +132,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
|
||||
override val isOpen: Boolean get() = channel.isOpen
|
||||
|
||||
private lateinit var loginHandler: LoginHandler
|
||||
private var loginHandler: LoginHandler? = null
|
||||
|
||||
private suspend fun processReceive() {
|
||||
while (channel.isOpen) {
|
||||
@ -186,7 +180,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
|
||||
val packet = try {
|
||||
with(id.factory) {
|
||||
loginHandler.provideDecrypter(id.factory)
|
||||
loginHandler!!.provideDecrypter(id.factory)
|
||||
.decrypt(input)
|
||||
.decode(id, sequenceId, this@TIMBotNetworkHandler)
|
||||
}
|
||||
@ -205,7 +199,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
}
|
||||
|
||||
internal suspend fun resendTouch(): LoginResult /* = coroutineScope */ {
|
||||
if (::loginHandler.isInitialized) loginHandler.close()
|
||||
loginHandler?.close()
|
||||
|
||||
loginHandler = LoginHandler(configuration)
|
||||
|
||||
@ -265,11 +259,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
}
|
||||
}
|
||||
|
||||
// They should be called in sequence because packet is lock-free
|
||||
loginHandler.onPacketReceived(packet)
|
||||
this@TIMBotNetworkHandler.forEach {
|
||||
it.instance.onPacketReceived(packet)
|
||||
}
|
||||
loginHandler?.onPacketReceived(packet)
|
||||
}
|
||||
|
||||
override suspend fun sendPacket(packet: OutgoingPacket): Unit = withContext(coroutineContext + CoroutineName("sendPacket")) {
|
||||
@ -319,7 +309,8 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
override val owner: Bot get() = this@TIMBotNetworkHandler.bot
|
||||
|
||||
override fun close() {
|
||||
if (::loginHandler.isInitialized) loginHandler.close()
|
||||
loginHandler?.close()
|
||||
loginHandler = null
|
||||
this.channel.close()
|
||||
}
|
||||
}
|
||||
@ -334,7 +325,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
private lateinit var loginIP: String
|
||||
private var privateKey: PrivateKey = PrivateKey(getRandomByteArray(16))
|
||||
|
||||
private var sessionResponseDecryptionKey: SessionResponseDecryptionKey by Delegates.notNull()
|
||||
private var sessionResponseDecryptionKey: SessionResponseDecryptionKey? = null
|
||||
|
||||
private var captchaSectionId: Int = 1
|
||||
private var captchaCache: IoBuffer? = null
|
||||
@ -359,7 +350,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
|
||||
NoDecrypter -> NoDecrypter
|
||||
|
||||
SessionResponseDecryptionKey -> sessionResponseDecryptionKey
|
||||
SessionResponseDecryptionKey -> sessionResponseDecryptionKey!!
|
||||
SubmitPasswordResponseDecrypter -> SubmitPasswordResponseDecrypter(privateKey)
|
||||
PrivateKey -> privateKey
|
||||
SessionKey -> sessionKey
|
||||
|
@ -1,74 +0,0 @@
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
|
||||
|
||||
package net.mamoe.mirai.network.protocol.tim.handler
|
||||
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.mamoe.mirai.network.BotSession
|
||||
import net.mamoe.mirai.network.isOpen
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.Packet
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.action.RequestAccountInfoPacket
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.RequestSKeyPacket
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.SKey
|
||||
import net.mamoe.mirai.network.qqAccount
|
||||
|
||||
/**
|
||||
* 动作: 获取好友列表, 点赞, 踢人等.
|
||||
* 处理动作事件, 承担动作任务.
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
class ActionPacketHandler(session: BotSession) : PacketHandler(session) {
|
||||
companion object Key : PacketHandler.Key<ActionPacketHandler>
|
||||
|
||||
|
||||
private var sKeyRefresherJob: Job? = null
|
||||
|
||||
|
||||
override suspend fun onPacketReceived(packet: Packet): Unit = with(session) {
|
||||
when (packet) {
|
||||
is SKey -> {
|
||||
_sKey = packet.value
|
||||
cookies = "uin=o$qqAccount;skey=$sKey;"
|
||||
|
||||
|
||||
if (sKeyRefresherJob?.isActive != true) {
|
||||
sKeyRefresherJob = NetworkScope.launch {
|
||||
while (isOpen) {
|
||||
delay(1800000)
|
||||
try {
|
||||
requestSKey()
|
||||
} catch (e: Throwable) {
|
||||
bot.logger.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun requestSKey() = with(session) {
|
||||
withContext(NetworkScope.coroutineContext) {
|
||||
RequestSKeyPacket().send()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suspend fun requestAccountInfo() = with(session) {
|
||||
withContext(NetworkScope.coroutineContext) {
|
||||
RequestAccountInfoPacket(qqAccount, sessionKey).send()
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
this.sKeyRefresherJob?.cancel()
|
||||
this.sKeyRefresherJob = null
|
||||
}
|
||||
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package net.mamoe.mirai.network.protocol.tim.handler
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import net.mamoe.mirai.network.BotSession
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.Packet
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
||||
/**
|
||||
* 数据包(接受/发送)处理器
|
||||
*/
|
||||
abstract class PacketHandler(
|
||||
val session: BotSession
|
||||
) : CoroutineScope {
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = EmptyCoroutineContext
|
||||
|
||||
abstract suspend fun onPacketReceived(packet: Packet)
|
||||
|
||||
interface Key<T : PacketHandler>
|
||||
|
||||
open fun close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
internal class PacketHandlerNode<T : PacketHandler>(
|
||||
val instance: T,
|
||||
val key: PacketHandler.Key<T>
|
||||
)
|
||||
|
||||
internal fun <T : PacketHandler> T.asNode(key: PacketHandler.Key<T>): PacketHandlerNode<T> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return PacketHandlerNode(this, key)
|
||||
}
|
||||
|
||||
internal open class PacketHandlerList : MutableList<PacketHandlerNode<*>> by mutableListOf() {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
operator fun <T : PacketHandler> get(key: PacketHandler.Key<T>): T = this.first { it.key == key }.instance as T
|
||||
}
|
@ -11,6 +11,7 @@ import net.mamoe.mirai.network.protocol.tim.TIMProtocol
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.*
|
||||
import net.mamoe.mirai.network.qqAccount
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
import net.mamoe.mirai.withSession
|
||||
|
||||
fun BotSession.RequestSKeyPacket(): OutgoingPacket = RequestSKeyPacket(qqAccount, sessionKey)
|
||||
|
||||
@ -39,6 +40,26 @@ object RequestSKeyPacket : SessionPacketFactory<SKey>() {
|
||||
DebugLogger.warning("SKey 包后面${readRemainingBytes().toUHexString()}")
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun BotNetworkHandler<*>.handlePacket(packet: SKey) = bot.withSession {
|
||||
_sKey = packet.value
|
||||
_cookies = "uin=o$qqAccount;skey=$sKey;"
|
||||
|
||||
// TODO: 2019/11/27 SKEY 实现
|
||||
/*
|
||||
if (sKeyRefresherJob?.isActive != true) {
|
||||
sKeyRefresherJob = NetworkScope.launch {
|
||||
while (isOpen) {
|
||||
delay(1800000)
|
||||
try {
|
||||
requestSKey()
|
||||
} catch (e: Throwable) {
|
||||
bot.logger.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
inline class SKey(
|
||||
|
Loading…
Reference in New Issue
Block a user