diff --git a/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java b/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java index a768ff60f..af7dcfdc7 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java @@ -5,6 +5,7 @@ import net.mamoe.mirai.event.MiraiEventManager; import net.mamoe.mirai.event.events.server.ServerDisableEvent; import net.mamoe.mirai.event.events.server.ServerEnableEvent; import net.mamoe.mirai.network.RobotNetworkHandler; +import net.mamoe.mirai.network.packet.login.LoginState; import net.mamoe.mirai.task.MiraiTaskManager; import net.mamoe.mirai.utils.LoggerTextFormat; import net.mamoe.mirai.utils.MiraiLogger; @@ -120,11 +121,16 @@ public class MiraiServer { this.qqs.keySet().stream().map(key -> this.qqs.getSection(key)).forEach(section -> { try { Robot robot = new Robot(section); - RobotNetworkHandler robotNetworkHandler = robot.getHandler(); - robotNetworkHandler.setServerIP("14.116.136.106"); - robotNetworkHandler.touch$mirai_core(); + RobotNetworkHandler robotNetworkHandler = robot.getNetworkHandler(); + robotNetworkHandler.tryLogin$mirai_core(state -> { + if (state == LoginState.SUCCEED) { + Robot.instances.add(robot); + } else { + robot.close(); + } + return null; + }); - Robot.instances.add(robot); } catch (Throwable e) { e.printStackTrace(); getLogger().error("Could not load QQ robots config!"); diff --git a/mirai-core/src/main/java/net/mamoe/mirai/Robot.java b/mirai-core/src/main/java/net/mamoe/mirai/Robot.java index 20b6c922a..fbc066118 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/Robot.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/Robot.java @@ -7,18 +7,19 @@ import net.mamoe.mirai.network.RobotNetworkHandler; import net.mamoe.mirai.utils.ContactList; import net.mamoe.mirai.utils.config.MiraiConfigSection; +import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; -public class Robot { +public class Robot implements Closeable { public static final List instances = Collections.synchronizedList(new LinkedList<>()); private final long qqNumber; private final String password; @Getter - private final RobotNetworkHandler handler; + private final RobotNetworkHandler networkHandler; /** * Ref list @@ -29,6 +30,14 @@ public class Robot { private final ContactList groups = new ContactList<>(); private final ContactList qqs = new ContactList<>(); + public void close() { + this.networkHandler.close(); + this.owners.clear(); + this.groups.values().forEach(Group::close); + this.groups.clear(); + this.qqs.clear(); + } + public boolean isOwnBy(String ownerName) { return owners.contains(ownerName); } @@ -50,7 +59,7 @@ public class Robot { this.qqNumber = qqNumber; this.password = password; this.owners = Collections.unmodifiableList(owners); - this.handler = new RobotNetworkHandler(this, this.qqNumber, this.password); + this.networkHandler = new RobotNetworkHandler(this, this.qqNumber, this.password); } public QQ getQQ(long qqNumber) { diff --git a/mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt b/mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt index 2d8677058..3d23d53b7 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/contact/Group.kt @@ -2,8 +2,9 @@ package net.mamoe.mirai.contact import net.mamoe.mirai.message.Message import net.mamoe.mirai.utils.ContactList +import java.io.Closeable -class Group(number: Long) : Contact(number) { +class Group(number: Long) : Contact(number), Closeable { val groupId = groupNumberToId(number) val members = ContactList() @@ -15,6 +16,10 @@ class Group(number: Long) : Contact(number) { } + override fun close() { + this.members.clear() + } + companion object { fun groupNumberToId(number: Long): Long { val left: Long = number.toString().let { @@ -53,11 +58,6 @@ class Group(number: Long) : Contact(number) { } } - @JvmStatic - fun main(args: Array) { - groupNumberToId(580266363) - } - fun groupIdToNumber(id: Long): Long { var left: Long = id.toString().let { if (it.length < 6) { diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotEvents.kt b/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotEvents.kt index 581f92e87..737c47d58 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotEvents.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/event/events/robot/RobotEvents.kt @@ -1,16 +1,16 @@ package net.mamoe.mirai.event.events.robot +import net.mamoe.mirai.Robot import net.mamoe.mirai.event.events.MiraiEvent -import net.mamoe.mirai.network.RobotNetworkHandler /** * @author Him188moe */ -class RobotLoginEvent(val robotNetworkHandler: RobotNetworkHandler) : MiraiEvent() +class RobotLoginEvent(val robot: Robot) : MiraiEvent() -class RobotLogoutEvent(val robotNetworkHandler: RobotNetworkHandler) : MiraiEvent() +class RobotLogoutEvent(val robot: Robot) : MiraiEvent() -class RobotMessageReceivedEvent(val robotNetworkHandler: RobotNetworkHandler, val type: Type, val message: String) : MiraiEvent() { +class RobotMessageReceivedEvent(val robot: Robot, val type: Type, val message: String) : MiraiEvent() { enum class Type { FRIEND, GROUP diff --git a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/At.java b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/At.java index 003d40850..d552e53c4 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/At.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/At.java @@ -26,6 +26,7 @@ public final class At extends Message { @Override public String toString() { - return null; + // TODO: 2019/9/4 At.toString + throw new UnsupportedOperationException(); } } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt index 8e0e5a363..e62c95502 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt @@ -11,6 +11,7 @@ import net.mamoe.mirai.network.packet.message.ServerSendFriendMessageResponsePac import net.mamoe.mirai.network.packet.message.ServerSendGroupMessageResponsePacket import net.mamoe.mirai.task.MiraiThreadPool import net.mamoe.mirai.utils.* +import java.io.Closeable import java.net.DatagramPacket import java.net.DatagramSocket import java.net.InetSocketAddress @@ -23,7 +24,7 @@ import java.util.concurrent.TimeUnit * @author Him188moe */ @ExperimentalUnsignedTypes -class RobotNetworkHandler(val robot: Robot, val number: Long, private val password: String) { +internal class RobotNetworkHandler(val robot: Robot, val number: Long, private val password: String) : Closeable { var socket: DatagramSocket = DatagramSocket((15314 + Math.random() * 100).toInt()) @@ -36,6 +37,7 @@ class RobotNetworkHandler(val robot: Robot, val number: Long, private val passwo } private lateinit var serverAddress: InetSocketAddress + private var closed: Boolean = false private lateinit var token00BA: ByteArray //这些数据全部是login用的 private lateinit var token0825: ByteArray @@ -60,6 +62,16 @@ class RobotNetworkHandler(val robot: Robot, val number: Long, private val passwo private var gtk: Int = 0 private var ignoreMessage: Boolean = false + private var loginState: LoginState? = null + set(value) { + field = value + if (value != null) { + loginHook?.invoke(value) + } + } + + private var loginHook: ((LoginState) -> Unit)? = null + init { tlv0105 = lazyEncode { it.writeHex("01 05 00 30") @@ -74,15 +86,37 @@ class RobotNetworkHandler(val robot: Robot, val number: Long, private val passwo @ExperimentalUnsignedTypes private var md5_32: ByteArray = getRandomKey(32) + /** + * Try to login to server + */ + internal fun tryLogin(loginHook: ((LoginState) -> Unit)? = null) { +//"14.116.136.106", + tryLogin() + } - internal fun touch() { + /** + * Try to login to server + */ + private fun tryLogin(serverAddress: String, loginHook: ((LoginState) -> Unit)? = null) { + + touch(serverAddress, loginHook) + } + + /** + * Start network + */ + private fun touch(serverAddress: String, loginHook: ((LoginState) -> Unit)? = null) { + serverIP = serverAddress + if (loginHook != null) { + this.loginHook = loginHook + } this.sendPacket(ClientTouchPacket(this.number, this.serverIP)) } private fun restartSocket() { socket.close() socket = DatagramSocket((15314 + Math.random() * 100).toInt()) - socket.connect(this.serverAddress) + socket.connect(this.serverAddress).runCatching { } val zeroByte: Byte = 0 Thread { while (true) { @@ -91,11 +125,14 @@ class RobotNetworkHandler(val robot: Robot, val number: Long, private val passwo socket.receive(dp1) } catch (e: Exception) { if (e.message == "socket closed") { + if (!closed) { + restartSocket() + } return@Thread } } MiraiThreadPool.getInstance().submit { - var i = dp1.data.size - 1; + var i = dp1.data.size - 1 while (dp1.data[i] == zeroByte) { --i } @@ -132,7 +169,8 @@ class RobotNetworkHandler(val robot: Robot, val number: Long, private val passwo } is ServerLoginResponseFailedPacket -> { - MiraiLogger error "Login failed: " + packet.state.toString() + this.loginState = packet.loginState + MiraiLogger error "Login failed: " + packet.loginState.toString() return } @@ -157,7 +195,7 @@ class RobotNetworkHandler(val robot: Robot, val number: Long, private val passwo is ServerVerificationCodeTransmissionPacket -> { this.verificationCodeSequence++ - this.verificationCodeCache = this.verificationCodeCache!! + packet.verificationCodePart2 + this.verificationCodeCache = this.verificationCodeCache!! + packet.verificationCodePartN this.verificationToken = packet.verificationToken this.verificationCodeCacheCount++ @@ -236,6 +274,7 @@ class RobotNetworkHandler(val robot: Robot, val number: Long, private val passwo } is ServerLoginSuccessPacket -> { + loginState = LoginState.SUCCEED sendPacket(ClientSKeyRequestPacket(this.number, this.sessionKey)) } @@ -328,4 +367,12 @@ class RobotNetworkHandler(val robot: Robot, val number: Long, private val passwo } } } + + override fun close() { + this.socket.close() + this.loginState = null + this.loginHook = null + this.verificationCodeCache = null + this.tgtgtKey = null + } } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt index 6c18807e8..7ea56c462 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt @@ -140,8 +140,6 @@ fun DataOutputStream.writeTLV0006(qq: Long, password: String, loginTime: Int, lo val md5_1 = md5(password); val md5_2 = md5(md5_1 + "00 00 00 00".hexToBytes() + qq.toUInt().toByteArray()) - println(md5_1.toUByteArray().toUHexString()) - println(md5_2.toUByteArray().toUHexString()) it.write(md5_1) it.writeInt(loginTime) it.writeByte(0); @@ -151,8 +149,6 @@ fun DataOutputStream.writeTLV0006(qq: Long, password: String, loginTime: Int, lo it.writeHex("00 10") it.writeHex("15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B") it.write(tgtgtKey) - println() - println(it.toByteArray().toUHexString()) this.write(TEACryptor.encrypt(it.toByteArray(), md5_2)) } } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt index 02fcfc719..acf94031d 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt @@ -2,6 +2,7 @@ package net.mamoe.mirai.network.packet import net.mamoe.mirai.message.defaults.MessageChain import net.mamoe.mirai.message.defaults.PlainText +import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.toUHexString import java.io.ByteArrayOutputStream import java.io.DataInputStream @@ -77,7 +78,7 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray, 25 -> MessageType.ANONYMOUS else -> { - println("id=$id") + MiraiLogger debug ("ServerGroupMessageEventPacket id=$id") MessageType.OTHER } } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt index dbe4d4599..980bf9961 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt @@ -3,6 +3,7 @@ package net.mamoe.mirai.network.packet import net.mamoe.mirai.network.packet.login.* import net.mamoe.mirai.network.packet.message.ServerSendFriendMessageResponsePacket import net.mamoe.mirai.network.packet.message.ServerSendGroupMessageResponsePacket +import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.getAllDeclaredFields import net.mamoe.mirai.utils.hexToBytes import net.mamoe.mirai.utils.toUHexString @@ -36,7 +37,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { 271, 207 -> return ServerLoginResponseResendPacketEncrypted(stream, when (idHex) { "08 36 31 03" -> ServerLoginResponseResendPacket.Flag.`08 36 31 03` else -> { - println("flag=$idHex"); ServerLoginResponseResendPacket.Flag.OTHER + MiraiLogger debug ("ServerLoginResponseResendPacketEncrypted: flag=$idHex"); ServerLoginResponseResendPacket.Flag.OTHER } }) 871 -> return ServerLoginResponseVerificationCodePacketEncrypted(stream) @@ -47,16 +48,16 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { } return ServerLoginResponseFailedPacket(when (bytes.size) { - 319 -> ServerLoginResponseFailedPacket.State.WRONG_PASSWORD - 135 -> ServerLoginResponseFailedPacket.State.RETYPE_PASSWORD - 279 -> ServerLoginResponseFailedPacket.State.BLOCKED - 263 -> ServerLoginResponseFailedPacket.State.UNKNOWN_QQ_NUMBER - 551, 487 -> ServerLoginResponseFailedPacket.State.DEVICE_LOCK - 359 -> ServerLoginResponseFailedPacket.State.TAKEN_BACK + 319 -> LoginState.WRONG_PASSWORD + 135 -> LoginState.RETYPE_PASSWORD + 279 -> LoginState.BLOCKED + 263 -> LoginState.UNKNOWN_QQ_NUMBER + 551, 487 -> LoginState.DEVICE_LOCK + 359 -> LoginState.TAKEN_BACK //unknown - 63 -> throw IllegalArgumentException(bytes.size.toString() + " (Unknown error)")//可能是已经完成登录, 服务器拒绝第二次登录 - 351 -> throw IllegalArgumentException(bytes.size.toString() + " (Illegal package data)")//包数据有误 + 63 -> throw IllegalArgumentException(bytes.size.toString() + " (Unknown error)") + 351 -> throw IllegalArgumentException(bytes.size.toString() + " (Illegal package data or Unknown error)")//包数据有误 else -> throw IllegalArgumentException(bytes.size.toString()) }, stream) @@ -88,6 +89,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { } } + @ExperimentalUnsignedTypes override fun toString(): String { return this.javaClass.simpleName + this.getAllDeclaredFields().joinToString(", ", "{", "}") { it.trySetAccessible(); it.name + "=" + it.get(this).let { value -> diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt index d79cabe9f..ba3e8d377 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt @@ -6,6 +6,9 @@ import net.mamoe.mirai.utils.* import java.io.DataInputStream +/** + * 客户端请求验证码图片数据的第几部分 + */ @ExperimentalUnsignedTypes @PacketId("00 BA 31") class ClientVerificationCodeTransmissionRequestPacket( @@ -40,11 +43,13 @@ class ClientVerificationCodeTransmissionRequestPacket( } /** + * 服务器发送验证码图片文件一部分过来 + * * @author Him188moe */ -class ServerVerificationCodeTransmissionPacket(input: DataInputStream, val dataSize: Int, val packetId: ByteArray) : ServerVerificationCodePacket(input) { +class ServerVerificationCodeTransmissionPacket(input: DataInputStream, private val dataSize: Int, private val packetId: ByteArray) : ServerVerificationCodePacket(input) { - lateinit var verificationCodePart2: ByteArray + lateinit var verificationCodePartN: ByteArray lateinit var verificationToken: ByteArray//56bytes var transmissionCompleted: Boolean = false//验证码是否已经传输完成 lateinit var token00BA: ByteArray//40 bytes @@ -55,10 +60,10 @@ class ServerVerificationCodeTransmissionPacket(input: DataInputStream, val dataS this.verificationToken = this.input.readNBytesAt(10, 56) val length = this.input.readShortAt(66) - this.verificationCodePart2 = this.input.readNBytes(length) + this.verificationCodePartN = this.input.readNBytes(length) this.input.skip(2) - this.transmissionCompleted = this.input.readBoolean() + this.transmissionCompleted = this.input.readBoolean().not() this.token00BA = this.input.readNBytesAt(dataSize - 57, 40) this.count = byteArrayOf(0, 0, packetId[2], packetId[3]).toUHexString().hexToInt() @@ -66,6 +71,8 @@ class ServerVerificationCodeTransmissionPacket(input: DataInputStream, val dataS } /** + * 暂不了解意义 + * * @author Him188moe */ class ServerVerificationCodeRepeatPacket(input: DataInputStream) : ServerVerificationCodePacket(input) { diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/LoginState.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/LoginState.kt new file mode 100644 index 000000000..7be53ad7d --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/LoginState.kt @@ -0,0 +1,18 @@ +package net.mamoe.mirai.network.packet.login + +/** + * @author Him188moe + */ +enum class LoginState { + SUCCEED, + + WRONG_PASSWORD, + // UNKNOWN,//? 要再次发送某数据包 + RETYPE_PASSWORD,//similar to [WRONG_PASSWORD] + BLOCKED,//你的帐号存在被盗风险,已进入保护模式 + UNKNOWN_QQ_NUMBER,//你输入的帐号不存在 + DEVICE_LOCK,//设备锁 + TAKEN_BACK,//被回收 + // VERIFICATION_CODE,//需要验证码 + // SUCCEED, +} \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseFailedPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseFailedPacket.kt index 5276b7f39..6c1915094 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseFailedPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseFailedPacket.kt @@ -6,19 +6,7 @@ import java.io.DataInputStream /** * @author Him188moe */ -class ServerLoginResponseFailedPacket(val state: State, input: DataInputStream) : ServerPacket(input) { - enum class State { - WRONG_PASSWORD, - // UNKNOWN,//? 要再次发送某数据包 - RETYPE_PASSWORD,//similar to [WRONG_PASSWORD] - BLOCKED,//你的帐号存在被盗风险,已进入保护模式 - UNKNOWN_QQ_NUMBER,//你输入的帐号不存在 - DEVICE_LOCK,//设备锁 - TAKEN_BACK,//被回收 - // VERIFICATION_CODE,//需要验证码 - // SUCCEED, - } - +class ServerLoginResponseFailedPacket(val loginState: LoginState, input: DataInputStream) : ServerPacket(input) { override fun decode() { } } \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseResendPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseResendPacket.kt index 7372b1ff8..0303fcb6e 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseResendPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseResendPacket.kt @@ -6,8 +6,6 @@ import net.mamoe.mirai.network.packet.dataInputStream import net.mamoe.mirai.network.packet.goto import net.mamoe.mirai.util.TestedSuccessfully import net.mamoe.mirai.utils.TEACryptor -import net.mamoe.mirai.utils.hexToUBytes -import net.mamoe.mirai.utils.toUHexString import java.io.DataInputStream /** @@ -61,17 +59,4 @@ class ServerLoginResponseResendPacketEncrypted(input: DataInputStream, private v data = TEACryptor.decrypt(data, tgtgtKey) return ServerLoginResponseResendPacket(data.dataInputStream(), flag) } -} - -fun main() { - val tgtgtkey = "9E 83 61 FF 18 61 4B 77 34 FE 1C 9C E2 03 B4 F2".hexToUBytes() - - ServerLoginResponseResendPacketEncrypted("02 37 13 08 36 31 03 76 E4 B8 DD 00 00 00 94 9B 87 00 87 7F 9E D0 E5 6A F6 17 41 02 0C AA F3 AC C8 CF 4E C6 9D EC FA 6C BD F8 7C 4B A5 28 80 CC DE B5 0A 41 8E 63 CE 5E 30 D8 A6 83 92 0E 2E 5C 35 E5 6E 62 3D FE 17 DD 7C 47 9A AD EF F0 F7 2A 6F 21 32 99 1B 6D E1 DA BE 68 2F 26 A9 93 DE 1B 4F 11 F0 AF A1 06 7B 85 53 46 D2 A3 DD A6 BE F2 76 8A 61 BF 15 FD 17 C4 45 DB EC 05 51 56 46 63 48 87 49 79 0D 40 DF 9D D9 99 93 EC D0 44 7B 4A 79 EB BD 08 10 18 29 0E 85 EE 26 A0 CD 40 00 2F 3E ED F4 A4 C3 01 5E 82 F5 A8 02 FA 70 EB F2 07 AD FF 0E DA 08 7A 3A FE B6 F4 5D 98 18 F7 58 C2 19 21 AF 29 D2 95 16 CE C4 A3 5F B0 E6 23 C2 B2 C6 5F 03 42 C2 44 C2 B0 A0 3F 95 8E 89 EF FC EC E4 BF 03 CB DA 9C D3 84 3F 9B A0 F1 B4 14 6E 23 D5 74 79 6F 89 DA B8 33 DB EF 0B 21 E1 27 27 57 8B 56 CB D9 BF C2 A8 25 6E 48 23 EB 31 9D 03".hexToUBytes().toByteArray().dataInputStream(), ServerLoginResponseResendPacket.Flag.`08 36 31 03`).decrypt(tgtgtkey.toByteArray()).let { it.decode();println(it._0836_tlv0006_encr.toUHexString()) } - - val data = "94 9B 87 00 87 7F 9E D0 E5 6A F6 17 41 02 0C AA F3 AC C8 CF 4E C6 9D EC FA 6C BD F8 7C 4B A5 28 80 CC DE B5 0A 41 8E 63 CE 5E 30 D8 A6 83 92 0E 2E 5C 35 E5 6E 62 3D FE 17 DD 7C 47 9A AD EF F0 F7 2A 6F 21 32 99 1B 6D E1 DA BE 68 2F 26 A9 93 DE 1B 4F 11 F0 AF A1 06 7B 85 53 46 D2 A3 DD A6 BE F2 76 8A 61 BF 15 FD 17 C4 45 DB EC 05 51 56 46 63 48 87 49 79 0D 40 DF 9D D9 99 93 EC D0 44 7B 4A 79 EB BD 08 10 18 29 0E 85 EE 26 A0 CD 40 00 2F 3E ED F4 A4 C3 01 5E 82 F5 A8 02 FA 70 EB F2 07 AD FF 0E DA 08 7A 3A FE B6 F4 5D 98 18 F7 58 C2 19 21 AF 29 D2 95 16 CE C4 A3 5F B0 E6 23 C2 B2 C6 5F 03 42 C2 44 C2 B0 A0 3F 95 8E 89 EF FC EC E4 BF 03 CB DA 9C D3 84 3F 9B A0 F1 B4 14 6E 23 D5 74 79 6F 89 DA B8 33 DB EF 0B 21 E1 27 27 57 8B 56 CB D9 BF C2 A8 25 6E 48 23 EB 31 9D".hexToUBytes() - - val d1 = TEACryptor.CRYPTOR_SHARE_KEY.decrypt(data.toByteArray()) - - ServerLoginResponseResendPacket(TEACryptor.decrypt(d1, tgtgtkey.toByteArray()).dataInputStream(), ServerLoginResponseResendPacket.Flag.`08 36 31 03`).let { it.decode();println(it._0836_tlv0006_encr.toUHexString()) } - } \ No newline at end of file