|
@@ -13,17 +13,12 @@ import net.mamoe.mirai.network.NetworkScope
|
|
import net.mamoe.mirai.network.protocol.tim.handler.*
|
|
import net.mamoe.mirai.network.protocol.tim.handler.*
|
|
import net.mamoe.mirai.network.protocol.tim.packet.*
|
|
import net.mamoe.mirai.network.protocol.tim.packet.*
|
|
import net.mamoe.mirai.network.protocol.tim.packet.login.*
|
|
import net.mamoe.mirai.network.protocol.tim.packet.login.*
|
|
-import net.mamoe.mirai.task.MiraiThreadPool
|
|
|
|
import net.mamoe.mirai.utils.*
|
|
import net.mamoe.mirai.utils.*
|
|
-import java.io.Closeable
|
|
|
|
import java.io.File
|
|
import java.io.File
|
|
import java.net.DatagramPacket
|
|
import java.net.DatagramPacket
|
|
import java.net.DatagramSocket
|
|
import java.net.DatagramSocket
|
|
import java.net.InetSocketAddress
|
|
import java.net.InetSocketAddress
|
|
import java.util.*
|
|
import java.util.*
|
|
-import java.util.concurrent.CompletableFuture
|
|
|
|
-import java.util.concurrent.ScheduledFuture
|
|
|
|
-import java.util.concurrent.TimeUnit
|
|
|
|
import javax.imageio.ImageIO
|
|
import javax.imageio.ImageIO
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -53,28 +48,21 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
|
|
temporaryPacketHandlers.add(temporaryPacketHandler)
|
|
temporaryPacketHandlers.add(temporaryPacketHandler)
|
|
}
|
|
}
|
|
|
|
|
|
- override fun tryLogin(touchingTimeoutMillis: Long): CompletableDeferred<LoginState> {
|
|
|
|
- val ipQueue: LinkedList<String> = LinkedList(TIMProtocol.SERVER_IP)
|
|
|
|
- val future = CompletableDeferred<LoginState>()
|
|
|
|
|
|
+ override suspend fun tryLogin(touchingTimeoutMillis: Long): LoginState {
|
|
|
|
+ return loginInternal(touchingTimeoutMillis, LinkedList(TIMProtocol.SERVER_IP))
|
|
|
|
+ }
|
|
|
|
|
|
- fun login() {
|
|
|
|
- this.socket.close()
|
|
|
|
- val ip = ipQueue.poll()
|
|
|
|
- if (ip == null) {
|
|
|
|
- future.complete(LoginState.UNKNOWN)//所有服务器均返回 UNKNOWN
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
|
|
+ private suspend fun loginInternal(touchingTimeoutMillis: Long, ipQueue: LinkedList<String>): LoginState {
|
|
|
|
+ this.socket.close()
|
|
|
|
+ val ip = ipQueue.poll() ?: return LoginState.UNKNOWN//所有服务器均返回 UNKNOWN
|
|
|
|
|
|
- this.socket.touch(ip, touchingTimeoutMillis).get().let { state ->
|
|
|
|
- if (state == LoginState.UNKNOWN || state == LoginState.TIMEOUT) {
|
|
|
|
- login()//超时或未知, 重试连接下一个服务器
|
|
|
|
- } else {
|
|
|
|
- future.complete(state)
|
|
|
|
- }
|
|
|
|
|
|
+ return this.socket.touch(ip, touchingTimeoutMillis).await().let { state ->
|
|
|
|
+ if (state == LoginState.UNKNOWN || state == LoginState.TIMEOUT) {
|
|
|
|
+ loginInternal(touchingTimeoutMillis, ipQueue)//超时或未知, 重试连接下一个服务器
|
|
|
|
+ } else {
|
|
|
|
+ state
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- login()
|
|
|
|
- return future
|
|
|
|
}
|
|
}
|
|
|
|
|
|
//private | internal
|
|
//private | internal
|
|
@@ -97,7 +85,7 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
- internal inner class BotSocket : Closeable, DataPacketSocket {
|
|
|
|
|
|
+ internal inner class BotSocket : DataPacketSocket {
|
|
override suspend fun distributePacket(packet: ServerPacket) {
|
|
override suspend fun distributePacket(packet: ServerPacket) {
|
|
try {
|
|
try {
|
|
packet.decode()
|
|
packet.decode()
|
|
@@ -156,7 +144,7 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
|
|
restartSocket()
|
|
restartSocket()
|
|
}
|
|
}
|
|
|
|
|
|
- internal var loginFuture: CompletableFuture<LoginState>? = null
|
|
|
|
|
|
+ internal var loginResult: CompletableDeferred<LoginState>? = null
|
|
|
|
|
|
@Synchronized
|
|
@Synchronized
|
|
private fun restartSocket() {
|
|
private fun restartSocket() {
|
|
@@ -186,23 +174,23 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
|
|
/**
|
|
/**
|
|
* Start network and touch the server
|
|
* Start network and touch the server
|
|
*/
|
|
*/
|
|
- fun touch(serverAddress: String, timeoutMillis: Long): CompletableFuture<LoginState> {
|
|
|
|
|
|
+ fun touch(serverAddress: String, timeoutMillis: Long): CompletableDeferred<LoginState> {
|
|
bot.info("Connecting server: $serverAddress")
|
|
bot.info("Connecting server: $serverAddress")
|
|
if (this@TIMBotNetworkHandler::login.isInitialized) {
|
|
if (this@TIMBotNetworkHandler::login.isInitialized) {
|
|
login.close()
|
|
login.close()
|
|
}
|
|
}
|
|
login = Login()
|
|
login = Login()
|
|
- this.loginFuture = CompletableFuture()
|
|
|
|
|
|
+ this.loginResult = CompletableDeferred()
|
|
|
|
|
|
serverIP = serverAddress
|
|
serverIP = serverAddress
|
|
bot.waitForPacket(ServerPacket::class, timeoutMillis) {
|
|
bot.waitForPacket(ServerPacket::class, timeoutMillis) {
|
|
- loginFuture!!.complete(LoginState.TIMEOUT)
|
|
|
|
|
|
+ loginResult!!.complete(LoginState.TIMEOUT)
|
|
}
|
|
}
|
|
runBlocking {
|
|
runBlocking {
|
|
sendPacket(ClientTouchPacket(bot.account.qqNumber, serverIP))
|
|
sendPacket(ClientTouchPacket(bot.account.qqNumber, serverIP))
|
|
}
|
|
}
|
|
|
|
|
|
- return this.loginFuture!!
|
|
|
|
|
|
+ return this.loginResult!!
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -236,13 +224,14 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
|
|
|
|
|
|
override fun getOwner(): Bot = this@TIMBotNetworkHandler.bot
|
|
override fun getOwner(): Bot = this@TIMBotNetworkHandler.bot
|
|
|
|
|
|
|
|
+
|
|
override fun close() {
|
|
override fun close() {
|
|
this.socket?.close()
|
|
this.socket?.close()
|
|
- if (this.loginFuture != null) {
|
|
|
|
- if (!this.loginFuture!!.isDone) {
|
|
|
|
- this.loginFuture!!.cancel(true)
|
|
|
|
|
|
+ if (this.loginResult != null) {
|
|
|
|
+ if (!this.loginResult!!.isCompleted) {
|
|
|
|
+ this.loginResult!!.cancel(CancellationException("socket closed"))
|
|
}
|
|
}
|
|
- this.loginFuture = null
|
|
|
|
|
|
+ this.loginResult = null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -254,7 +243,7 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
|
|
/**
|
|
/**
|
|
* 处理登录过程
|
|
* 处理登录过程
|
|
*/
|
|
*/
|
|
- inner class Login : Closeable {
|
|
|
|
|
|
+ inner class Login {
|
|
private lateinit var token00BA: ByteArray
|
|
private lateinit var token00BA: ByteArray
|
|
private lateinit var token0825: ByteArray//56
|
|
private lateinit var token0825: ByteArray//56
|
|
private var loginTime: Int = 0
|
|
private var loginTime: Int = 0
|
|
@@ -269,7 +258,7 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
|
|
private var captchaSectionId: Int = 1
|
|
private var captchaSectionId: Int = 1
|
|
private var captchaCache: ByteArray? = byteArrayOf()//每次包只发一部分验证码来
|
|
private var captchaCache: ByteArray? = byteArrayOf()//每次包只发一部分验证码来
|
|
|
|
|
|
- private var heartbeatFuture: ScheduledFuture<*>? = null
|
|
|
|
|
|
+ private var heartbeatJob: Job? = null
|
|
|
|
|
|
|
|
|
|
suspend fun onPacketReceived(packet: ServerPacket) {
|
|
suspend fun onPacketReceived(packet: ServerPacket) {
|
|
@@ -289,7 +278,7 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
|
|
}
|
|
}
|
|
|
|
|
|
is ServerLoginResponseFailedPacket -> {
|
|
is ServerLoginResponseFailedPacket -> {
|
|
- socket.loginFuture?.complete(packet.loginState)
|
|
|
|
|
|
+ socket.loginResult?.complete(packet.loginState)
|
|
bot.close()
|
|
bot.close()
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -373,13 +362,13 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
|
|
|
|
|
|
is ServerSessionKeyResponsePacket -> {
|
|
is ServerSessionKeyResponsePacket -> {
|
|
sessionKey = packet.sessionKey
|
|
sessionKey = packet.sessionKey
|
|
- heartbeatFuture = MiraiThreadPool.getInstance().scheduleWithFixedDelay({
|
|
|
|
- runBlocking {
|
|
|
|
- socket.sendPacket(ClientHeartbeatPacket(bot.account.qqNumber, sessionKey))
|
|
|
|
- }
|
|
|
|
- }, 90000, 90000, TimeUnit.MILLISECONDS)
|
|
|
|
|
|
|
|
- socket.loginFuture!!.complete(LoginState.SUCCESS)
|
|
|
|
|
|
+ heartbeatJob = NetworkScope.launch {
|
|
|
|
+ delay(90000)
|
|
|
|
+ socket.sendPacket(ClientHeartbeatPacket(bot.account.qqNumber, sessionKey))
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ socket.loginResult!!.complete(LoginState.SUCCESS)
|
|
|
|
|
|
login.changeOnlineStatus(ClientLoginStatus.ONLINE)
|
|
login.changeOnlineStatus(ClientLoginStatus.ONLINE)
|
|
}
|
|
}
|
|
@@ -420,12 +409,12 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
|
|
socket.sendPacket(ClientChangeOnlineStatusPacket(bot.account.qqNumber, sessionKey, status))
|
|
socket.sendPacket(ClientChangeOnlineStatusPacket(bot.account.qqNumber, sessionKey, status))
|
|
}
|
|
}
|
|
|
|
|
|
- override fun close() {
|
|
|
|
|
|
+ fun close() {
|
|
this.captchaCache = null
|
|
this.captchaCache = null
|
|
|
|
|
|
- this.heartbeatFuture?.cancel(true)
|
|
|
|
|
|
+ this.heartbeatJob?.cancel(CancellationException("handler closed"))
|
|
|
|
|
|
- this.heartbeatFuture = null
|
|
|
|
|
|
+ this.heartbeatJob = null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|