mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-24 14:30:09 +08:00
Updated robot & network structure
This commit is contained in:
parent
1446618496
commit
402e8fbb32
@ -56,6 +56,12 @@
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.18</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
<version>1.3.41</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
@ -120,7 +120,7 @@ public class MiraiServer {
|
||||
this.qqs.keySet().stream().map(key -> this.qqs.getSection(key)).forEach(section -> {
|
||||
try {
|
||||
Robot robot = new Robot(section);
|
||||
robot.network.tryLogin$mirai_core(state -> {
|
||||
robot.network.tryLogin$mirai_core((robot1, state) -> {
|
||||
if (state == LoginState.SUCCEED) {
|
||||
Robot.instances.add(robot);
|
||||
} else {
|
||||
|
@ -89,7 +89,6 @@ public final class Robot implements Closeable {
|
||||
|
||||
public void close() {
|
||||
this.network.close();
|
||||
this.owners.clear();
|
||||
this.contacts.groups.values().forEach(Group::close);
|
||||
this.contacts.groups.clear();
|
||||
this.contacts.qqs.clear();
|
||||
|
@ -3,6 +3,9 @@ package net.mamoe.mirai.event
|
||||
import net.mamoe.mirai.event.events.MiraiEvent
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
object EventManager : MiraiEventManager()
|
||||
typealias MiraiEventManagerKt = EventManager
|
||||
typealias EventMgr = EventManager
|
||||
|
||||
fun <C : Class<E>, E : MiraiEvent> C.hookAlways(hook: (E) -> Unit) {
|
||||
MiraiEventManager.getInstance().hookAlways(MiraiEventHook<E>(this, hook))
|
@ -10,14 +10,12 @@ import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MiraiEventManager {
|
||||
private MiraiEventManager() {
|
||||
MiraiEventManager() {
|
||||
|
||||
}
|
||||
|
||||
private static MiraiEventManager instance = new MiraiEventManager();
|
||||
|
||||
public static MiraiEventManager getInstance() {
|
||||
return MiraiEventManager.instance;
|
||||
return EventManager.INSTANCE;
|
||||
}
|
||||
|
||||
private final ReentrantReadWriteLock hooksLock = new ReentrantReadWriteLock();
|
||||
|
@ -11,7 +11,7 @@ public abstract class MiraiEvent {
|
||||
|
||||
public boolean isCancelled() {
|
||||
if (!(this instanceof Cancellable)) {
|
||||
throw new EventException("Event is not Cancellable");
|
||||
return false;
|
||||
}
|
||||
return this.cancelled;
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
package net.mamoe.mirai.event.events.network;
|
||||
|
||||
import net.mamoe.mirai.event.events.MiraiEvent;
|
||||
import net.mamoe.mirai.network.packet.Packet;
|
||||
|
||||
/**
|
||||
* @author Him188moe
|
||||
*/
|
||||
public abstract class PacketEvent extends MiraiEvent {
|
||||
private final Packet packet;
|
||||
|
||||
public PacketEvent(Packet packet) {
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
public Packet getPacket() {
|
||||
return packet;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package net.mamoe.mirai.event.events.network;
|
||||
|
||||
/**
|
||||
* @author Him188moe
|
||||
*/
|
||||
public class PacketReceivedEvent {
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package net.mamoe.mirai.event.events.network;
|
||||
|
||||
import net.mamoe.mirai.network.packet.ServerPacket;
|
||||
|
||||
/**
|
||||
* @author Him188moe
|
||||
*/
|
||||
public abstract class ServerPacketEvent extends PacketEvent {
|
||||
public ServerPacketEvent(ServerPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerPacket getPacket() {
|
||||
return (ServerPacket) super.getPacket();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package net.mamoe.mirai.event.events.network;
|
||||
|
||||
import net.mamoe.mirai.event.events.Cancellable;
|
||||
import net.mamoe.mirai.network.packet.ServerPacket;
|
||||
|
||||
/**
|
||||
* @author Him188moe
|
||||
*/
|
||||
public class ServerPacketReceivedEvent extends ServerPacketEvent implements Cancellable {
|
||||
public ServerPacketReceivedEvent(ServerPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
}
|
@ -13,13 +13,13 @@ object Protocol {
|
||||
add("183.60.56.29")
|
||||
|
||||
arrayOf(
|
||||
"sz2.tencent.com",
|
||||
"sz3.tencent.com",
|
||||
"sz4.tencent.com",
|
||||
"sz5.tencent.com",
|
||||
"sz6.tencent.com",
|
||||
"sz8.tencent.com",
|
||||
"sz9.tencent.com"
|
||||
"sz9.tencent.com",
|
||||
"sz2.tencent.com"
|
||||
).forEach { this.add(InetAddress.getByName(it).hostAddress) }
|
||||
|
||||
}
|
||||
|
@ -3,8 +3,10 @@ package net.mamoe.mirai.network
|
||||
import net.mamoe.mirai.Robot
|
||||
import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.contact.QQ
|
||||
import net.mamoe.mirai.event.events.network.ServerPacketReceivedEvent
|
||||
import net.mamoe.mirai.event.events.qq.FriendMessageEvent
|
||||
import net.mamoe.mirai.event.events.robot.RobotLoginSucceedEvent
|
||||
import net.mamoe.mirai.event.hookWhile
|
||||
import net.mamoe.mirai.message.Message
|
||||
import net.mamoe.mirai.network.packet.*
|
||||
import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
|
||||
@ -35,7 +37,7 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
||||
val messageHandler = MessageHandler()
|
||||
val actionHandler = ActionHandler()
|
||||
|
||||
private val packetHandlers: Map<KClass<out PacketHandler>, PacketHandler> = mapOf(
|
||||
private val packetHandlers: Map<KClass<out PacketHandler>, PacketHandler> = linkedMapOf(
|
||||
DebugHandler::class to debugHandler,
|
||||
LoginHandler::class to loginHandler,
|
||||
MessageHandler::class to messageHandler,
|
||||
@ -63,16 +65,22 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
||||
|
||||
//private | internal
|
||||
|
||||
internal fun tryLogin(loginHook: ((LoginState) -> Unit)? = null) {
|
||||
/**
|
||||
* 仅当 [LoginState] 非 [LoginState.UNKNOWN] 且非 [LoginState.TIMEOUT] 才会调用 [loginHook].
|
||||
* 如果要输入验证码, 那么会以参数 [LoginState.VERIFICATION_CODE] 调用 [loginHandler], 登录完成后再以 [LoginState.SUCCEED] 调用 [loginHandler]
|
||||
*/
|
||||
internal fun tryLogin(loginHook: (Robot.(LoginState) -> Unit)? = null) {
|
||||
val ipQueue: LinkedList<String> = LinkedList(Protocol.SERVER_IP)
|
||||
fun login(): Boolean {
|
||||
val ip = ipQueue.poll()
|
||||
return if (ip != null) {
|
||||
this@RobotNetworkHandler.socketHandler.touch(ip) { state ->
|
||||
if (state == LoginState.UNKNOWN) {
|
||||
if (state == LoginState.UNKNOWN || state == LoginState.TIMEOUT) {
|
||||
login()
|
||||
} else {
|
||||
loginHook?.invoke(state)
|
||||
if (loginHook != null) {
|
||||
robot.loginHook(state)
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
@ -82,7 +90,12 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
internal fun onPacketReceived(packet: ServerPacket) {
|
||||
internal fun distributePacket(packet: ServerPacket) {
|
||||
packet.decode()
|
||||
if (ServerPacketReceivedEvent(packet).broadcast().isCancelled) {
|
||||
debugHandler.onPacketReceived(packet)
|
||||
return
|
||||
}
|
||||
this.packetHandlers.values.forEach {
|
||||
it.onPacketReceived(packet)
|
||||
}
|
||||
@ -90,11 +103,10 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
||||
|
||||
|
||||
private inner class SocketHandler : Closeable {
|
||||
private lateinit var socket: DatagramSocket
|
||||
private var socket: DatagramSocket? = null
|
||||
|
||||
internal var serverIP: String = ""
|
||||
set(value) {
|
||||
serverAddress = InetSocketAddress(value, 8000)
|
||||
field = value
|
||||
|
||||
restartSocket()
|
||||
@ -104,36 +116,29 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
||||
internal var loginState: LoginState? = null
|
||||
set(value) {
|
||||
field = value
|
||||
if (value != null && value != LoginState.UNKNOWN) {
|
||||
if (value != null) {
|
||||
loginHook?.invoke(value)
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var serverAddress: InetSocketAddress
|
||||
|
||||
private fun restartSocket() {
|
||||
|
||||
socket = DatagramSocket((15314 + Math.random() * 100).toInt())
|
||||
socket.close()
|
||||
socket.connect(this.serverAddress)
|
||||
socket?.close()
|
||||
socket = DatagramSocket(0)
|
||||
socket!!.connect(InetSocketAddress(serverIP, 8000))
|
||||
Thread {
|
||||
while (socket.isConnected) {
|
||||
while (socket!!.isConnected) {
|
||||
val packet = DatagramPacket(ByteArray(2048), 2048)
|
||||
kotlin
|
||||
.runCatching { socket.receive(packet) }
|
||||
kotlin.runCatching { socket!!.receive(packet) }
|
||||
.onSuccess {
|
||||
MiraiThreadPool.getInstance().submit {
|
||||
try {
|
||||
onPacketReceived(ServerPacket.ofByteArray(packet.data.removeZeroTail()))
|
||||
distributePacket(ServerPacket.ofByteArray(packet.data.removeZeroTail()))
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}.onFailure {
|
||||
if (it.message == "socket closed") {
|
||||
if (!closed) {
|
||||
restartSocket()
|
||||
}
|
||||
if (it.message == "Socket closed" || it.message == "socket closed") {
|
||||
return@Thread
|
||||
}
|
||||
it.printStackTrace()
|
||||
@ -147,11 +152,16 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
||||
* Start network and touch the server
|
||||
*/
|
||||
internal fun touch(serverAddress: String, loginHook: ((LoginState) -> Unit)? = null) {
|
||||
MiraiLogger.info("Connecting server: $serverAddress")
|
||||
socketHandler.serverIP = serverAddress
|
||||
if (loginHook != null) {
|
||||
this.loginHook = loginHook
|
||||
}
|
||||
sendPacket(ClientTouchPacket(robot.account.qqNumber, socketHandler.serverIP))
|
||||
waitForPacket(ServerTouchResponsePacket::class, 100) {
|
||||
MiraiLogger.error(" Timeout")
|
||||
loginHook?.invoke(LoginState.TIMEOUT)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,20 +169,46 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
internal fun sendPacket(packet: ClientPacket) {
|
||||
checkNotNull(socket) { "socket closed" }
|
||||
|
||||
try {
|
||||
packet.encode()
|
||||
packet.writeHex(Protocol.tail)
|
||||
|
||||
val data = packet.toByteArray()
|
||||
socket.send(DatagramPacket(data, data.size))
|
||||
socket!!.send(DatagramPacket(data, data.size))
|
||||
MiraiLogger info "Packet sent: $packet"
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <P : ServerPacket> waitForPacket(packetClass: KClass<P>, timeoutMillis: Long, timeout: () -> Unit) {
|
||||
var got = false
|
||||
ServerPacketReceivedEvent::class.hookWhile {
|
||||
if (packetClass.isInstance(it.packet)) {
|
||||
got = true
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
MiraiThreadPool.getInstance().submit {
|
||||
val startingTime = System.currentTimeMillis()
|
||||
while (!got) {
|
||||
if (System.currentTimeMillis() - startingTime > timeoutMillis) {
|
||||
timeout.invoke()
|
||||
return@submit
|
||||
}
|
||||
Thread.sleep(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
this.socket.close()
|
||||
this.socket?.close()
|
||||
this.loginState = null
|
||||
this.loginHook = null
|
||||
}
|
||||
@ -194,7 +230,6 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
||||
*/
|
||||
inner class DebugHandler : PacketHandler() {
|
||||
override fun onPacketReceived(packet: ServerPacket) {
|
||||
packet.decode()
|
||||
MiraiLogger info "Packet received: $packet"
|
||||
if (packet is ServerEventPacket) {
|
||||
sendPacket(ClientMessageResponsePacket(robot.account.qqNumber, packet.packetId, sessionKey, packet.eventIdentity))
|
||||
@ -274,6 +309,8 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
||||
}
|
||||
|
||||
is ServerVerificationCodeTransmissionPacket -> {
|
||||
socketHandler.loginState = LoginState.VERIFICATION_CODE
|
||||
|
||||
this.verificationCodeSequence++
|
||||
this.verificationCodeCache = this.verificationCodeCache!! + packet.verificationCodePartN
|
||||
|
||||
@ -371,17 +408,17 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
||||
sendPacket(ClientAccountInfoRequestPacket(robot.account.qqNumber, sessionKey))
|
||||
}
|
||||
|
||||
is ServerEventPacket.Raw -> onPacketReceived(packet.distribute())
|
||||
is ServerEventPacket.Raw -> distributePacket(packet.distribute())
|
||||
|
||||
is ServerVerificationCodePacket.Encrypted -> onPacketReceived(packet.decrypt())
|
||||
is ServerLoginResponseVerificationCodeInitPacket.Encrypted -> onPacketReceived(packet.decrypt())
|
||||
is ServerLoginResponseResendPacket.Encrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
|
||||
is ServerLoginResponseSuccessPacket.Encrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
|
||||
is ServerSessionKeyResponsePacket.Encrypted -> onPacketReceived(packet.decrypt(this.sessionResponseDecryptionKey))
|
||||
is ServerTouchResponsePacket.Encrypted -> onPacketReceived(packet.decrypt())
|
||||
is ServerSKeyResponsePacket.Encrypted -> onPacketReceived(packet.decrypt(sessionKey))
|
||||
is ServerAccountInfoResponsePacket.Encrypted -> onPacketReceived(packet.decrypt(sessionKey))
|
||||
is ServerEventPacket.Raw.Encrypted -> onPacketReceived(packet.decrypt(sessionKey))
|
||||
is ServerVerificationCodePacket.Encrypted -> distributePacket(packet.decrypt())
|
||||
is ServerLoginResponseVerificationCodeInitPacket.Encrypted -> distributePacket(packet.decrypt())
|
||||
is ServerLoginResponseResendPacket.Encrypted -> distributePacket(packet.decrypt(this.tgtgtKey!!))
|
||||
is ServerLoginResponseSuccessPacket.Encrypted -> distributePacket(packet.decrypt(this.tgtgtKey!!))
|
||||
is ServerSessionKeyResponsePacket.Encrypted -> distributePacket(packet.decrypt(this.sessionResponseDecryptionKey))
|
||||
is ServerTouchResponsePacket.Encrypted -> distributePacket(packet.decrypt())
|
||||
is ServerSKeyResponsePacket.Encrypted -> distributePacket(packet.decrypt(sessionKey))
|
||||
is ServerAccountInfoResponsePacket.Encrypted -> distributePacket(packet.decrypt(sessionKey))
|
||||
is ServerEventPacket.Raw.Encrypted -> distributePacket(packet.decrypt(sessionKey))
|
||||
|
||||
|
||||
is ServerAccountInfoResponsePacket,
|
||||
|
@ -152,10 +152,6 @@ fun DataOutputStream.writeTLV0006(qq: Long, password: String, loginTime: Int, lo
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ExperimentalUnsignedTypes
|
||||
fun main() {
|
||||
@ -164,7 +160,7 @@ fun main() {
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
@TestedSuccessfully
|
||||
fun DataOutputStream.writeCRC32() = writeCRC32(getRandomKey(16))
|
||||
fun DataOutputStream.writeCRC32() = writeCRC32(getRandomByteArray(16))
|
||||
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
@ -3,7 +3,7 @@ package net.mamoe.mirai.network.packet
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
import net.mamoe.mirai.utils.ByteArrayDataOutputStream
|
||||
import net.mamoe.mirai.utils.TEA
|
||||
import net.mamoe.mirai.utils.getRandomKey
|
||||
import net.mamoe.mirai.utils.getRandomByteArray
|
||||
import net.mamoe.mirai.utils.lazyEncode
|
||||
import java.io.DataInputStream
|
||||
import java.net.InetAddress
|
||||
@ -44,12 +44,12 @@ class ClientSessionRequestPacket(
|
||||
this.write(tlv0105)
|
||||
this.writeHex("01 0B 00 85 00 02")
|
||||
this.writeHex("B9 ED EF D7 CD E5 47 96 7A B5 28 34 CA 93 6B 5C")//fix2
|
||||
this.write(getRandomKey(1))
|
||||
this.write(getRandomByteArray(1))
|
||||
this.writeHex("10 00 00 00 00 00 00 00 02")
|
||||
|
||||
//fix3
|
||||
this.writeHex("00 63 3E 00 63 02 04 03 06 02 00 04 00 52 D9 00 00 00 00 A9 58 3E 6D 6D 49 AA F6 A6 D9 33 0A E7 7E 36 84 03 01 00 00 68 20 15 8B 00 00 01 02 00 00 03 00 07 DF 00 0A 00 0C 00 01 00 04 00 03 00 04 20 5C 00")
|
||||
this.write(getRandomKey(32))//md5 32
|
||||
this.write(getRandomByteArray(32))//md5 32
|
||||
this.writeHex("68")
|
||||
|
||||
this.writeHex("00 00 00 00 00 2D 00 06 00 01")
|
||||
|
@ -40,7 +40,7 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
|
||||
|
||||
loginTime = input.readInt()
|
||||
loginIP = input.readIP()
|
||||
tgtgtKey = getRandomKey(16)
|
||||
tgtgtKey = getRandomByteArray(16)
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
@ -82,7 +82,7 @@ class ServerVerificationCodeRepeatPacket(input: DataInputStream) : ServerVerific
|
||||
@ExperimentalUnsignedTypes
|
||||
override fun decode() {
|
||||
token00BA = this.input.readNBytesAt(10, 56)
|
||||
tgtgtKeyUpdate = getRandomKey(16)
|
||||
tgtgtKeyUpdate = getRandomByteArray(16)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,11 @@ enum class LoginState {
|
||||
UNKNOWN_QQ_NUMBER,//你输入的帐号不存在
|
||||
DEVICE_LOCK,//设备锁
|
||||
TAKEN_BACK,//被回收
|
||||
// VERIFICATION_CODE,//需要验证码
|
||||
|
||||
|
||||
VERIFICATION_CODE,//需要验证码
|
||||
|
||||
|
||||
UNKNOWN,
|
||||
TIMEOUT,
|
||||
}
|
@ -69,7 +69,7 @@ open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream())
|
||||
fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDataOutputStream().let { t(it); return it.toByteArray() }
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun getRandomKey(length: Int): ByteArray {
|
||||
fun getRandomByteArray(length: Int): ByteArray {
|
||||
val bytes = LinkedList<Byte>()
|
||||
repeat(length) { bytes.add((Math.random() * 255).toByte()) }
|
||||
return bytes.toByteArray()
|
||||
|
127
mirai-core/src/test/java/BadQQFilter.kt
Normal file
127
mirai-core/src/test/java/BadQQFilter.kt
Normal file
@ -0,0 +1,127 @@
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import net.mamoe.mirai.Robot
|
||||
import net.mamoe.mirai.network.packet.login.LoginState
|
||||
import net.mamoe.mirai.utils.RobotAccount
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* @author Him188moe
|
||||
*/
|
||||
|
||||
val qqList = "2258868346----123456789.\n" +
|
||||
"1545483785----yuk7k1dxnf3jn5\n" +
|
||||
"2948786488----123123123\n" +
|
||||
"3059674084----qq123456\n" +
|
||||
"1918079979----123456789.\n" +
|
||||
"3050478794----18872590321\n" +
|
||||
"3331537204----123456789.\n" +
|
||||
"2128659972----123456789.\n" +
|
||||
"3435376516----abc123456\n" +
|
||||
"2980527804----a123456\n" +
|
||||
"2752195782----qq123456789\n" +
|
||||
"3130257966----13415986622\n" +
|
||||
"1802730396----123456789\n" +
|
||||
"3021732783----15866103923\n" +
|
||||
"306499606----abc123456\n" +
|
||||
"2893904328----abc123456\n" +
|
||||
"1765904806----123456789\n" +
|
||||
"3254202261----15223045268\n" +
|
||||
"2947707697----abc123456\n" +
|
||||
"3500959200----123456789.\n" +
|
||||
"2169513531----123456789.\n" +
|
||||
"2983688661----a123456\n" +
|
||||
"1246882194----pz49779866\n" +
|
||||
"2315275635----147258369\n" +
|
||||
"2802294904----123456789\n" +
|
||||
"2955364492----1234567890\n" +
|
||||
"1753325115----123456789\n" +
|
||||
"2642725191----qq123456\n" +
|
||||
"2152972686----123456789.\n" +
|
||||
"2845953617----123456789.\n" +
|
||||
"3329641753----123456789.\n" +
|
||||
"1458302685----123456789a\n" +
|
||||
"2351156352----987654321\n" +
|
||||
"2304786984----fkhwt53787\n" +
|
||||
"3322756212----123456789.\n" +
|
||||
"3187253283----123456789.\n" +
|
||||
"3168715730----147258369\n" +
|
||||
"2189916732----18831892323\n" +
|
||||
"2965337631----123456789.\n" +
|
||||
"1901802165----123456789.\n" +
|
||||
"414015319----abc123456\n" +
|
||||
"3400636089----123456789a\n" +
|
||||
"3530336304----seoua80060\n" +
|
||||
"3147312971----123456789.\n" +
|
||||
"3011083526----yp70y9\n" +
|
||||
"286888078----abc123456\n" +
|
||||
"3126754112----1234567890\n" +
|
||||
"2924643025----123123123\n" +
|
||||
"341870356----ncvhZtQD\n" +
|
||||
"3358177328----123456789a\n" +
|
||||
"1396419201----eakuj14475\n" +
|
||||
"3541159580----123456789.\n" +
|
||||
"2540245592----1234567890\n" +
|
||||
"2024802855----123456789.\n" +
|
||||
"2578309660----1234567890\n" +
|
||||
"1934965091----123456789.\n" +
|
||||
"3449408956----a123456789\n" +
|
||||
"2509348670----123456789.\n" +
|
||||
"2305961679----123456789.\n" +
|
||||
"3532858521----123456789.\n" +
|
||||
"3308276898----123456789a\n" +
|
||||
"1760897490----123456789\n" +
|
||||
"2920800012----123123123\n" +
|
||||
"2923942248----123123123\n" +
|
||||
"3216600579----13882755274\n" +
|
||||
"3100259299----qq123456\n" +
|
||||
"3242723735----1234567890\n" +
|
||||
"2142733062----123456789.\n" +
|
||||
"1557689693----123456789\n" +
|
||||
"3505693439----sb2662vqy6q\n" +
|
||||
"3231125974----123456789.\n" +
|
||||
"3433048975----13893690883\n" +
|
||||
"3168017129----18780999209\n" +
|
||||
"2922045831----123123123\n" +
|
||||
"3578152022----a123456789\n" +
|
||||
"2116254935----147258369\n" +
|
||||
"3158479284----1234567890\n" +
|
||||
"3149394424----qq123456789\n" +
|
||||
"2829521712----123456789.\n" +
|
||||
"3218671461----123456789.\n" +
|
||||
"3035873094----123456789a\n" +
|
||||
"2224518667----147258369\n" +
|
||||
"3175801590----123456789.\n" +
|
||||
"3203228181----123456789a\n" +
|
||||
"3213497536----123456789a\n" +
|
||||
"3377317115----123456789\n" +
|
||||
"2672537341----qq123456789\n" +
|
||||
"2945957617----123123123\n" +
|
||||
"2763390197----123456789.\n" +
|
||||
"3322711709----123456789."
|
||||
|
||||
|
||||
fun main() {
|
||||
val goodRobotList = Collections.synchronizedList(mutableListOf<Robot>())
|
||||
|
||||
qqList.split("\n").forEach {
|
||||
GlobalScope.launch {
|
||||
val strings = it.split("----")
|
||||
Robot(RobotAccount(strings[0].toLong(), strings[1].let { password ->
|
||||
if (password.endsWith(".")) {
|
||||
return@let password.substring(0, password.length - 1)
|
||||
}
|
||||
return@let password
|
||||
}), listOf()).network.tryLogin { state ->
|
||||
if (!(state == LoginState.BLOCKED || state == LoginState.DEVICE_LOCK || state == LoginState.WRONG_PASSWORD)) {
|
||||
goodRobotList.add(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Thread.sleep(9 * 3000)
|
||||
|
||||
println(goodRobotList.joinToString("\n") { it.account.qqNumber.toString() + " " + it.account.password })
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user