1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-03-26 07:20:09 +08:00

Small updates

This commit is contained in:
Him188 2019-10-03 21:12:54 +08:00
parent ba7e50de31
commit 624d471432
15 changed files with 138 additions and 186 deletions

View File

@ -29,6 +29,8 @@ kotlin {
}
}
jvmTest {
}
all {
languageSettings.enableLanguageFeature("InlineClasses")
@ -36,7 +38,7 @@ kotlin {
}
}
compileKotlinJvm{
compileKotlinJvm {
}

View File

@ -27,7 +27,7 @@ val Bot.qqs: ContactList<QQ> get() = this.contacts.qqs
//NetworkHandler
suspend fun Bot.sendPacket(packet: ClientPacket) = this.network.socket.sendPacket(packet)
suspend fun Bot.login(touchingTimeoutMillis: Long = 200): LoginState = this.network.login()
suspend fun Bot.login(): LoginState = this.network.login()
//BotAccount

View File

@ -54,10 +54,8 @@ interface BotNetworkHandler {
/**
* 尝试登录
*
* @param touchingTimeoutMillis 连接每个服务器的 timeout
*/
suspend fun login(touchingTimeoutMillis: Long = 200): LoginState
suspend fun login(): LoginState
/**
* 添加一个临时包处理器

View File

@ -1,6 +1,8 @@
package net.mamoe.mirai.network.protocol.tim
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.bot.BotLoginSucceedEvent
@ -48,20 +50,20 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
temporaryPacketHandlers.add(temporaryPacketHandler)
}
override suspend fun login(touchingTimeoutMillis: Long): LoginState {
return loginInternal(touchingTimeoutMillis, LinkedList(TIMProtocol.SERVER_IP))
override suspend fun login(): LoginState {
return loginInternal(LinkedList(TIMProtocol.SERVER_IP))
}
private suspend fun loginInternal(touchingTimeoutMillis: Long, ipQueue: LinkedList<String>): LoginState {
private suspend fun loginInternal(ipQueue: LinkedList<String>): LoginState {
this.socket.close()
val ip = ipQueue.poll() ?: return LoginState.UNKNOWN//所有服务器均返回 UNKNOWN
return this.socket.touch(ip, touchingTimeoutMillis).await().let { state ->
if (state == LoginState.UNKNOWN || state == LoginState.TIMEOUT) {
loginInternal(touchingTimeoutMillis, ipQueue)//超时或未知, 重试连接下一个服务器
} else {
return socket.touch(ip).let { state ->
//if (state == LoginState.UNKNOWN || state == LoginState.TIMEOUT) {
// loginInternal(ipQueue)//超时或未知, 重试连接下一个服务器
//} else {
state
}
// }
}
}
@ -121,14 +123,14 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
return
}
withContext(NetworkScope.coroutineContext) {
launch {
withContext(NetworkScope.coroutineContext + CoroutineExceptionHandler { _, e -> e.printStackTrace() }) {
launch(this.coroutineContext) {
loginHandler.onPacketReceived(packet)
}
packetHandlers.forEach {
launch {
launch(this.coroutineContext) {
it.instance.onPacketReceived(packet)
}
}
@ -151,10 +153,10 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
socket?.close()
socket = DatagramSocket(0)
socket!!.connect(InetSocketAddress(serverIP, 8000))
GlobalScope.launch {
NetworkScope.launch {
while (socket?.isConnected == true) {
val packet = DatagramPacket(ByteArray(2048), 2048)
kotlin.runCatching { socket?.receive(packet) }
kotlin.runCatching { withContext(Dispatchers.IO) { socket?.receive(packet) } }
.onSuccess {
NetworkScope.launch {
distributePacket(ServerPacket.ofByteArray(packet.data.removeZeroTail()))
@ -174,8 +176,9 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
/**
* Start network and touch the server
*/
fun touch(serverAddress: String, timeoutMillis: Long): CompletableDeferred<LoginState> {
internal suspend fun touch(serverAddress: String): LoginState {
bot.info("Connecting server: $serverAddress")
restartSocket()
if (this@TIMBotNetworkHandler::loginHandler.isInitialized) {
loginHandler.close()
}
@ -183,19 +186,16 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
this.loginResult = CompletableDeferred()
serverIP = serverAddress
bot.waitForPacket(ServerPacket::class, timeoutMillis) {
loginResult!!.complete(LoginState.TIMEOUT)
}
runBlocking {
sendPacket(ClientTouchPacket(bot.account.qqNumber, serverIP))
}
//bot.waitForPacket(ServerTouchResponsePacket::class, timeoutMillis) {
// loginResult?.complete(LoginState.TIMEOUT)
//}
sendPacket(ClientTouchPacket(bot.account.qqNumber, serverIP))
return this.loginResult!!
return withContext(Dispatchers.IO) {
loginResult!!.await()
}
}
/**
* Not async
*/
@Synchronized
override suspend fun sendPacket(packet: ClientPacket) {
checkNotNull(socket) { "network closed" }
@ -240,6 +240,10 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
}
}
companion object {
val captchaLock = Mutex()
}
/**
* 处理登录过程
*/
@ -312,21 +316,24 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
if (packet.transmissionCompleted) {
//todo 验证码多样化处理
withContext(Dispatchers.IO) {
bot.notice(CharImageUtil.createCharImg(ImageIO.read(captchaCache!!.inputStream())))
val code = captchaLock.withLock {
withContext(Dispatchers.IO) {
bot.notice(ImageIO.read(captchaCache!!.inputStream()).createCharImg())
}
bot.notice("需要验证码登录, 验证码为 4 字母")
try {
File(System.getProperty("user.dir") + "/temp/Captcha.png")
.also { withContext(Dispatchers.IO) { it.createNewFile() } }
.writeBytes(this.captchaCache!!)
bot.notice("若看不清字符图片, 请查看 Mirai 目录下 /temp/Captcha.png")
} catch (e: Exception) {
bot.notice("无法写出验证码文件, 请尝试查看以上字符图片")
}
this.captchaCache = null
bot.notice("若要更换验证码, 请直接回车")
Scanner(System.`in`).nextLine()
}
bot.notice("需要验证码登录, 验证码为 4 字母")
try {
File(System.getProperty("user.dir") + "/temp/Captcha.png")
.also { withContext(Dispatchers.IO) { it.createNewFile() } }
.writeBytes(this.captchaCache!!)
bot.notice("若看不清字符图片, 请查看 Mirai 目录下 /temp/Captcha.png")
} catch (e: Exception) {
bot.notice("无法写出验证码文件, 请尝试查看以上字符图片")
}
this.captchaCache = null
bot.notice("若要更换验证码, 请直接回车")
val code = Scanner(System.`in`).nextLine()
if (code.isEmpty() || code.length != 4) {
this.captchaCache = byteArrayOf()
this.captchaSectionId = 1

View File

@ -2,8 +2,10 @@
package net.mamoe.mirai.network.protocol.tim.packet
import kotlinx.coroutines.*
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.network.ServerPacketReceivedEvent
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeWhileTrue
import net.mamoe.mirai.network.protocol.tim.packet.PacketNameFormatter.adjustName
import net.mamoe.mirai.network.protocol.tim.packet.action.ServerCanAddFriendResponsePacket
@ -337,42 +339,19 @@ fun DataInputStream.gotoWhere(matcher: ByteArray): DataInputStream {
@Suppress("UNCHECKED_CAST")
internal fun <P : ServerPacket> Bot.waitForPacket(packetClass: KClass<P>, timeoutMillis: Long = Long.MAX_VALUE, timeout: () -> Unit = {}) {
var got = false
ServerPacketReceivedEvent::class.subscribeWhileTrue {
ServerPacketReceivedEvent.subscribeWhileTrue {
if (packetClass.isInstance(it.packet) && it.bot === this) {
got = true
true
} else {
false
} else {
true
}
}
MiraiThreadPool.instance.submit {
val startingTime = System.currentTimeMillis()
while (!got) {
if (System.currentTimeMillis() - startingTime > timeoutMillis) {
timeout.invoke()
return@submit
}
Thread.sleep(10)
GlobalScope.launch(Dispatchers.Unconfined) {
delay(timeoutMillis)
if (!got) {
timeout.invoke()
}
}
}
/*
@Throws(EOFException::class)
fun DataInputStream.gotoWhere(matcher: ByteArray) {
require(matcher.isNotEmpty())
do {
val byte = this.readByte()
if (byte == matcher[0]) {
for (i in 1 until matcher.size){
}
}
} while (true)
}*/
fun ByteArray.cutTail(length: Int): ByteArray = this.copyOfRange(0, this.size - length)
fun ByteArray.getRight(length: Int): ByteArray = this.copyOfRange(this.size - length, this.size)
}

View File

@ -4,6 +4,7 @@ import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.*
import net.mamoe.mirai.utils.TEA
import net.mamoe.mirai.utils.Tested
import net.mamoe.mirai.utils.cutTail
import net.mamoe.mirai.utils.hexToBytes
import java.io.DataInputStream

View File

@ -5,11 +5,7 @@ import java.awt.image.BufferedImage
/**
* @author NaturalHG
*/
object CharImageUtil {
@JvmOverloads
fun createCharImg(image: BufferedImage, sizeWeight: Int = 100, sizeHeight: Int = 20): String {
return CharImageConverter(image, sizeWeight).call()
}
@JvmOverloads
fun BufferedImage.createCharImg(sizeWeight: Int = 100, sizeHeight: Int = 20): String {
return CharImageConverter(this, sizeWeight).call()
}

View File

@ -33,7 +33,7 @@ interface MiraiLogger {
/**
* mirai-console mirai-web 等模块实现
*/
lateinit var defaultLogger: () -> MiraiLogger
var defaultLogger: () -> MiraiLogger = { Console() }
val DEBUGGING: Boolean by lazy {
//avoid inspections

View File

@ -167,4 +167,9 @@ object GZip {
GZIPOutputStream(it).write(bytes)
return it.toByteArray()
}
}
}
fun ByteArray.cutTail(length: Int): ByteArray = this.copyOfRange(0, this.size - length)
fun ByteArray.getRight(length: Int): ByteArray = this.copyOfRange(this.size - length, this.size)

View File

@ -0,0 +1,67 @@
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import net.mamoe.mirai.Bot
import net.mamoe.mirai.login
import net.mamoe.mirai.network.NetworkScope
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginState
import net.mamoe.mirai.utils.BotAccount
import net.mamoe.mirai.utils.Console
import java.util.*
/**
* 筛选掉无法登录(冻结/设备锁/UNKNOWN) qq
*
* @author Him188moe
*/
const val qqList = "" +
"3383596103----13978930542\n" +
"3342679146----aaaa9899\n" +
"1491095272----abc123\n" +
"3361065539----aaaa9899\n" +
"1077612696----asd123456789\n" +
"\n" +
"\n" +
"\n" +
"\n" +
"\n" +
"\n" +
"\n" +
"\n" +
"\n" +
"\n"
suspend fun main() {
val goodBotList = Collections.synchronizedList(mutableListOf<Bot>())
withContext(NetworkScope.coroutineContext) {
qqList.split("\n")
.filterNot { it.isEmpty() }
.map { it.split("----") }
.map { Pair(it[0].toLong(), it[1]) }
.forEach { (qq, password) ->
runBlocking {
val bot = Bot(
BotAccount(
qq,
if (password.endsWith(".")) password.substring(0, password.length - 1) else password
),
Console()
)
withContext(Dispatchers.IO) {
bot.login()
}.let { state ->
if (state == LoginState.SUCCESS) {
goodBotList.add(bot)
}
}
}
}
}
println("Filtering finished")
println(goodBotList.joinToString("\n") { it.account.qqNumber.toString() + " " + it.account.password })
}

View File

@ -1,103 +0,0 @@
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout
import net.mamoe.mirai.Bot
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginState
import net.mamoe.mirai.utils.BotAccount
import net.mamoe.mirai.utils.Console
import java.util.*
/**
* 筛选掉无法登录(冻结/设备锁/UNKNOWN) qq
*
* @author Him188moe
*/
val qqList = "2535777366----abc123456\n" +
"2535815148----abc123456\n" +
"2535704896----abc123456\n" +
"2535744882----abc123456\n" +
"2535656918----abc123456\n" +
"2535679286----abc123456\n" +
"2535606374----abc123456\n" +
"2535647743----abc123456\n" +
"2535543049----abc123456\n" +
"2535583893----abc123456\n" +
"2535508338----abc123456\n" +
"2535524178----abc123456\n" +
"2535363077----abc123456\n" +
"2535469090----abc123456\n" +
"2535263758----abc123456\n" +
"2535258328----abc123456\n" +
"2535175332----abc123456\n" +
"2535175855----abc123456\n" +
"2535126490----abc123456\n" +
"2535169081----abc123456\n" +
"2535054551----abc123456\n" +
"2535085068----abc123456\n" +
"2535041182----abc123456\n" +
"2535055583----abc123456\n" +
"2534883752----abc123456\n" +
"2534909231----abc123456\n" +
"2534715278----abc123456\n" +
"2534766467----abc123456\n" +
"2534696956----abc123456\n" +
"2534703892----abc123456\n" +
"2534597961----abc123456\n" +
"2534687923----abc123456\n" +
"2534573690----abc123456\n" +
"2534596747----abc123456\n" +
"2534467863----abc123456\n" +
"2534480141----abc123456\n" +
"2534377951----abc123456\n" +
"2534418547----abc123456\n" +
"2534315990----abc123456\n" +
"2534318348----abc123456\n" +
"2534220616----abc123456\n" +
"2534288430----abc123456\n" +
"2534205633----abc123456\n" +
"2534226589----abc123456\n" +
"2534182470----abc123456\n" +
"2534194558----abc123456\n" +
"2534106061----abc123456\n" +
"2534108283----abc123456\n" +
"2534026460----abc123456\n" +
"2534037598----abc123456\n"
suspend fun main() {
val goodBotList = Collections.synchronizedList(mutableListOf<Bot>())
withContext(Dispatchers.Default) {
qqList.split("\n")
.filterNot { it.isEmpty() }
.map { it.split("----") }
.map { Pair(it[0].toLong(), it[1]) }
.forEach { (qq, password) ->
launch {
val bot = Bot(
BotAccount(
qq,
if (password.endsWith(".")) password.substring(0, password.length - 1) else password
),
Console()
)
withContext(Dispatchers.IO) {
withTimeout(3000) {
bot.network.tryLogin().await()
}
}.let { state ->
if (!(state == LoginState.BLOCKED || state == LoginState.DEVICE_LOCK || state == LoginState.WRONG_PASSWORD)) {
goodBotList.add(bot)
} else {
}
}
}
}
}
println(goodBotList.joinToString("\n") { it.account.qqNumber.toString() + " " + it.account.password })
}