Commit e129719d authored by Him188moe's avatar Him188moe

Updated robot & network structure

parent c353e8e8
......@@ -10,7 +10,7 @@ class Group(robot: Robot, number: Long) : Contact(robot, number), Closeable {
val members = ContactList<QQ>()
override fun sendMessage(message: Message) {
robot.network.packetSystem.sendGroupMessage(this, message)
robot.network.messageHandler.sendGroupMessage(this, message)
}
override fun sendXMLMessage(message: String) {
......
......@@ -12,7 +12,7 @@ import net.mamoe.mirai.message.defaults.At
*/
class QQ(robot: Robot, number: Long) : Contact(robot, number) {
override fun sendMessage(message: Message) {
robot.network.packetSystem.sendFriendMessage(this, message)
robot.network.messageHandler.sendFriendMessage(this, message)
}
override fun sendXMLMessage(message: String) {
......
......@@ -7,9 +7,8 @@ import java.util.stream.Collectors
/**
* @author Him188moe
*/
interface Protocol {
companion object {
val SERVER_IP: ArrayList<String> = object : ArrayList<String>() {
object Protocol {
val SERVER_IP: List<String> = object : ArrayList<String>() {
init {
add("183.60.56.29")
......@@ -25,7 +24,7 @@ interface Protocol {
}
}
get() = Collections.unmodifiableList(field)
const val head = "02"
const val ver = "37 13"
......@@ -90,5 +89,4 @@ interface Protocol {
.map { s -> s.toUByte(16) }
.collect(Collectors.toList()).toUByteArray()
}
}
......@@ -11,15 +11,15 @@ import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePack
import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
import net.mamoe.mirai.network.packet.login.*
import net.mamoe.mirai.task.MiraiThreadPool
import net.mamoe.mirai.utils.ClientLoginStatus
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.getGTK
import net.mamoe.mirai.utils.lazyEncode
import net.mamoe.mirai.utils.*
import java.io.Closeable
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetSocketAddress
import java.util.*
import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit
import kotlin.reflect.KClass
/**
* A RobotNetworkHandler is used to connect with Tencent servers.
......@@ -28,150 +28,230 @@ import java.util.concurrent.TimeUnit
*/
@Suppress("EXPERIMENTAL_API_USAGE")//to simplify code
internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
private val socketHandler: SocketHandler = SocketHandler()
private var socket: DatagramSocket = DatagramSocket((15314 + Math.random() * 100).toInt())
val debugHandler = DebugHandler()
val loginHandler = LoginHandler()
val messageHandler = MessageHandler()
val actionHandler = ActionHandler()
private var serverIP: String = ""
set(value) {
serverAddress = InetSocketAddress(value, 8000)
field = value
private val packetHandlers: Map<KClass<out PacketHandler>, PacketHandler> = mapOf(
DebugHandler::class to debugHandler,
LoginHandler::class to loginHandler,
MessageHandler::class to messageHandler,
ActionHandler::class to actionHandler
)
restartSocket()
}
private lateinit var serverAddress: InetSocketAddress
private var closed: Boolean = false
private lateinit var token00BA: ByteArray //这些数据全部是login用的
private lateinit var token0825: ByteArray
private var loginTime: Int = 0
private lateinit var loginIP: String
private var tgtgtKey: ByteArray? = null
private var tlv0105: ByteArray
/**
* 0828_decr_key
*/
private lateinit var sessionResponseDecryptionKey: ByteArray
private var verificationCodeSequence: Int = 0//这两个验证码使用
private var verificationCodeCache: ByteArray? = null//每次包只发一部分验证码来
private var verificationCodeCacheCount: Int = 1//
private lateinit var verificationToken: ByteArray
private lateinit var sessionKey: ByteArray//这两个是登录成功后得到的
private lateinit var sKey: String
/**
* Used to access web API(for friends list etc.)
* Not async
*/
private lateinit var cookies: String
private var gtk: Int = 0
private var ignoreMessage: Boolean = false
@ExperimentalUnsignedTypes
fun sendPacket(packet: ClientPacket) {
socketHandler.sendPacket(packet)
}
private var loginState: LoginState? = null
set(value) {
field = value
if (value != null) {
loginHook?.invoke(value)
override fun close() {
this.packetHandlers.values.forEach {
it.close()
}
this.socketHandler.close()
}
private var loginHook: ((LoginState) -> Unit)? = null
init {
tlv0105 = lazyEncode {
it.writeHex("01 05 00 30")
it.writeHex("00 01 01 02 00 14 01 01 00 10")
it.writeRandom(16)
it.writeHex("00 14 01 02 00 10")
it.writeRandom(16)
//private | internal
internal fun tryLogin(loginHook: ((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) {
login()
} else {
loginHook?.invoke(state)
}
}
true
} else false
}
login()
}
/**
* Try to login to server
*/
internal fun tryLogin(loginHook: ((LoginState) -> Unit)? = null) {
//"14.116.136.106",
tryLogin()
@ExperimentalUnsignedTypes
internal fun onPacketReceived(packet: ServerPacket) {
this.packetHandlers.values.forEach {
it.onPacketReceived(packet)
}
}
/**
* Try to login to server
*/
private fun tryLogin(serverAddress: String, loginHook: ((LoginState) -> Unit)? = null) {
touch(serverAddress, loginHook)
private inner class SocketHandler : Closeable {
private lateinit var socket: DatagramSocket
internal var serverIP: String = ""
set(value) {
serverAddress = InetSocketAddress(value, 8000)
field = value
restartSocket()
}
/**
* Start network
*/
private fun touch(serverAddress: String, loginHook: ((LoginState) -> Unit)? = null) {
serverIP = serverAddress
if (loginHook != null) {
this.loginHook = loginHook
private var loginHook: ((LoginState) -> Unit)? = null
internal var loginState: LoginState? = null
set(value) {
field = value
if (value != null && value != LoginState.UNKNOWN) {
loginHook?.invoke(value)
}
this.sendPacket(ClientTouchPacket(this.robot.account.qqNumber, this.serverIP))
}
private lateinit var serverAddress: InetSocketAddress
private fun restartSocket() {
socket.close()
socket = DatagramSocket((15314 + Math.random() * 100).toInt())
socket.close()
socket.connect(this.serverAddress)
val zeroByte: Byte = 0
Thread {
while (true) {
val dp1 = DatagramPacket(ByteArray(2048), 2048)
while (socket.isConnected) {
val packet = DatagramPacket(ByteArray(2048), 2048)
kotlin
.runCatching { socket.receive(packet) }
.onSuccess {
MiraiThreadPool.getInstance().submit {
try {
socket.receive(dp1)
onPacketReceived(ServerPacket.ofByteArray(packet.data.removeZeroTail()))
} catch (e: Exception) {
if (e.message == "socket closed") {
e.printStackTrace()
}
}
}.onFailure {
if (it.message == "socket closed") {
if (!closed) {
restartSocket()
}
return@Thread
}
it.printStackTrace()
}
MiraiThreadPool.getInstance().submit {
var i = dp1.data.size - 1
while (dp1.data[i] == zeroByte) {
--i
}
}.start()
}
/**
* Start network and touch the server
*/
internal fun touch(serverAddress: String, loginHook: ((LoginState) -> Unit)? = null) {
socketHandler.serverIP = serverAddress
if (loginHook != null) {
this.loginHook = loginHook
}
sendPacket(ClientTouchPacket(robot.account.qqNumber, socketHandler.serverIP))
}
/**
* Not async
*/
@ExperimentalUnsignedTypes
internal fun sendPacket(packet: ClientPacket) {
try {
onPacketReceived(ServerPacket.ofByteArray(dp1.data.copyOfRange(0, i + 1)))
} catch (e: Exception) {
packet.encode()
packet.writeHex(Protocol.tail)
val data = packet.toByteArray()
socket.send(DatagramPacket(data, data.size))
MiraiLogger info "Packet sent: $packet"
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun close() {
this.socket.close()
this.loginState = null
this.loginHook = null
}
}.start()
}
@ExperimentalUnsignedTypes
internal fun onPacketReceived(packet: ServerPacket) {
private lateinit var sessionKey: ByteArray
abstract inner class PacketHandler : Closeable {
abstract fun onPacketReceived(packet: ServerPacket)
override fun close() {
}
}
/**
* Kind of [PacketHandler] that prints all packets received in the format of hex byte array.
*/
inner class DebugHandler : PacketHandler() {
override fun onPacketReceived(packet: ServerPacket) {
packet.decode()
MiraiLogger info "Packet received: $packet"
if (packet is ServerEventPacket) {
sendPacket(ClientMessageResponsePacket(this.robot.account.qqNumber, packet.packetId, this.sessionKey, packet.eventIdentity))
sendPacket(ClientMessageResponsePacket(robot.account.qqNumber, packet.packetId, sessionKey, packet.eventIdentity))
}
}
}
/**
* 处理登录过程
*/
inner class LoginHandler : PacketHandler() {
private lateinit var token00BA: ByteArray
private lateinit var token0825: ByteArray
private var loginTime: Int = 0
private lateinit var loginIP: String
private var tgtgtKey: ByteArray? = null
private var tlv0105: ByteArray = lazyEncode {
it.writeHex("01 05 00 30")
it.writeHex("00 01 01 02 00 14 01 01 00 10")
it.writeRandom(16)
it.writeHex("00 14 01 02 00 10")
it.writeRandom(16)
}
/**
* 0828_decr_key
*/
private lateinit var sessionResponseDecryptionKey: ByteArray
private var verificationCodeSequence: Int = 0//这两个验证码使用
private var verificationCodeCache: ByteArray? = null//每次包只发一部分验证码来
private var verificationCodeCacheCount: Int = 1//
private lateinit var verificationToken: ByteArray
private var heartbeatFuture: ScheduledFuture<*>? = null
private var sKeyRefresherFuture: ScheduledFuture<*>? = null
override fun onPacketReceived(packet: ServerPacket) {
when (packet) {
is ServerTouchResponsePacket -> {
if (packet.serverIP != null) {//redirection
serverIP = packet.serverIP!!
socketHandler.serverIP = packet.serverIP!!
//connect(packet.serverIP!!)
sendPacket(ClientServerRedirectionPacket(packet.serverIP!!, this.robot.account.qqNumber))
sendPacket(ClientServerRedirectionPacket(packet.serverIP!!, robot.account.qqNumber))
} else {//password submission
this.loginIP = packet.loginIP
this.loginTime = packet.loginTime
this.token0825 = packet.token0825
this.tgtgtKey = packet.tgtgtKey
sendPacket(ClientPasswordSubmissionPacket(this.robot.account.qqNumber, this.robot.account.password, packet.loginTime, packet.loginIP, packet.tgtgtKey, packet.token0825))
sendPacket(ClientPasswordSubmissionPacket(robot.account.qqNumber, robot.account.password, packet.loginTime, packet.loginIP, packet.tgtgtKey, packet.token0825))
}
}
is ServerLoginResponseFailedPacket -> {
this.loginState = packet.loginState
socketHandler.loginState = packet.loginState
MiraiLogger error "Login failed: " + packet.loginState.toString()
return
}
......@@ -181,18 +261,16 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
this.token00BA = packet.token00BA
this.verificationCodeCache = packet.verifyCodePart1
if (packet.unknownBoolean != null && packet.unknownBoolean!!) {
this.verificationCodeSequence = 1
sendPacket(ClientVerificationCodeTransmissionRequestPacket(1, this.robot.account.qqNumber, this.token0825, this.verificationCodeSequence, this.token00BA))
sendPacket(ClientVerificationCodeTransmissionRequestPacket(1, robot.account.qqNumber, this.token0825, this.verificationCodeSequence, this.token00BA))
}
}
is ServerVerificationCodeRepeatPacket -> {//todo 这个名字正确么
this.tgtgtKey = packet.tgtgtKeyUpdate
this.token00BA = packet.token00BA
sendPacket(ClientLoginResendPacket3105(this.robot.account.qqNumber, this.robot.account.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA))
sendPacket(ClientLoginResendPacket3105(robot.account.qqNumber, robot.account.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA))
}
is ServerVerificationCodeTransmissionPacket -> {
......@@ -207,18 +285,17 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
//todo 看易语言 count 和 sequence 是怎样变化的
if (packet.transmissionCompleted) {
this.verificationCodeCache
TODO("验证码好了")
} else {
sendPacket(ClientVerificationCodeTransmissionRequestPacket(this.verificationCodeCacheCount, this.robot.account.qqNumber, this.token0825, this.verificationCodeSequence, this.token00BA))
sendPacket(ClientVerificationCodeTransmissionRequestPacket(this.verificationCodeCacheCount, robot.account.qqNumber, this.token0825, this.verificationCodeSequence, this.token00BA))
}
}
is ServerLoginResponseSuccessPacket -> {
this.sessionResponseDecryptionKey = packet.sessionResponseDecryptionKey
sendPacket(ClientSessionRequestPacket(this.robot.account.qqNumber, this.serverIP, packet.token38, packet.token88, packet.encryptionKey, this.tlv0105))
sendPacket(ClientSessionRequestPacket(robot.account.qqNumber, socketHandler.serverIP, packet.token38, packet.token88, packet.encryptionKey, this.tlv0105))
}
//是ClientPasswordSubmissionPacket之后服务器回复的
......@@ -230,8 +307,8 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
if (packet.flag == ServerLoginResponseResendPacket.Flag.`08 36 31 03`) {
this.tgtgtKey = packet.tgtgtKey
sendPacket(ClientLoginResendPacket3104(
this.robot.account.qqNumber,
this.robot.account.password,
robot.account.qqNumber,
robot.account.password,
this.loginTime,
this.loginIP,
this.tgtgtKey!!,
......@@ -244,8 +321,8 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
))
} else {
sendPacket(ClientLoginResendPacket3106(
this.robot.account.qqNumber,
this.robot.account.password,
robot.account.qqNumber,
robot.account.password,
this.loginTime,
this.loginIP,
this.tgtgtKey!!,
......@@ -259,98 +336,113 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
}
}
is ServerSessionKeyResponsePacket -> {
this.sessionKey = packet.sessionKey
MiraiThreadPool.getInstance().scheduleWithFixedDelay({
sendPacket(ClientHeartbeatPacket(this.robot.account.qqNumber, this.sessionKey))
sessionKey = packet.sessionKey
heartbeatFuture = MiraiThreadPool.getInstance().scheduleWithFixedDelay({
sendPacket(ClientHeartbeatPacket(robot.account.qqNumber, sessionKey))
}, 90000, 90000, TimeUnit.MILLISECONDS)
RobotLoginSucceedEvent(robot).broadcast()
//登录成功后会收到大量上次的消息, 忽略掉
MiraiThreadPool.getInstance().schedule({
ignoreMessage = false
(packetHandlers[MessageHandler::class] as MessageHandler).ignoreMessage = false
}, 2, TimeUnit.SECONDS)
this.tlv0105 = packet.tlv0105
sendPacket(ClientChangeOnlineStatusPacket(this.robot.account.qqNumber, this.sessionKey, ClientLoginStatus.ONLINE))
sendPacket(ClientChangeOnlineStatusPacket(robot.account.qqNumber, sessionKey, ClientLoginStatus.ONLINE))
}
is ServerLoginSuccessPacket -> {
loginState = LoginState.SUCCEED
sendPacket(ClientSKeyRequestPacket(this.robot.account.qqNumber, this.sessionKey))
socketHandler.loginState = LoginState.SUCCEED
sendPacket(ClientSKeyRequestPacket(robot.account.qqNumber, sessionKey))
}
is ServerSKeyResponsePacket -> {
this.sKey = packet.sKey
this.cookies = "uin=o" + this.robot.account.qqNumber + ";skey=" + this.sKey + ";"
val actionHandler = packetHandlers[ActionHandler::class] as ActionHandler
actionHandler.sKey = packet.sKey
actionHandler.cookies = "uin=o" + robot.account.qqNumber + ";skey=" + actionHandler.sKey + ";"
MiraiThreadPool.getInstance().scheduleWithFixedDelay({
sendPacket(ClientSKeyRefreshmentRequestPacket(this.robot.account.qqNumber, this.sessionKey))
sKeyRefresherFuture = MiraiThreadPool.getInstance().scheduleWithFixedDelay({
sendPacket(ClientSKeyRefreshmentRequestPacket(robot.account.qqNumber, sessionKey))
}, 1800000, 1800000, TimeUnit.MILLISECONDS)
this.gtk = getGTK(sKey)
sendPacket(ClientAccountInfoRequestPacket(this.robot.account.qqNumber, this.sessionKey))
actionHandler.gtk = getGTK(actionHandler.sKey)
sendPacket(ClientAccountInfoRequestPacket(robot.account.qqNumber, sessionKey))
}
is ServerHeartbeatResponsePacket -> {
is ServerEventPacket.Raw -> onPacketReceived(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 ServerAccountInfoResponsePacket -> {
is ServerAccountInfoResponsePacket,
is ServerHeartbeatResponsePacket,
is UnknownServerPacket -> {
//ignored
}
else -> {
is ServerFriendMessageEventPacket -> {
if (ignoreMessage) {
return
}
FriendMessageEvent(this.robot, this.robot.contacts.getQQ(packet.qq), packet.message)
}
is ServerGroupMessageEventPacket -> {
//todo message chain
//GroupMessageEvent(this.robot, this.robot.contacts.getGroupByNumber(packet.groupNumber), this.robot.contacts.getQQ(packet.qq), packet.message)
}
is UnknownServerEventPacket -> {
//unknown message event
}
override fun close() {
this.verificationCodeCache = null
this.tgtgtKey = null
is UnknownServerPacket -> {
this.heartbeatFuture?.cancel(true)
this.sKeyRefresherFuture?.cancel(true)
this.heartbeatFuture = null
this.sKeyRefresherFuture = null
}
}
is ServerGroupUploadFileEventPacket -> {
/**
* 处理消息事件, 承担消息发送任务.
*/
inner class MessageHandler : PacketHandler() {
internal var ignoreMessage: Boolean = false
override fun onPacketReceived(packet: ServerPacket) {
when (packet) {
is ServerGroupUploadFileEventPacket -> {
//todo
}
is ServerEventPacket.Raw -> onPacketReceived(packet.distribute())
is ServerFriendMessageEventPacket -> {
if (ignoreMessage) {
return
}
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(this.sessionKey))
is ServerAccountInfoResponsePacket.Encrypted -> onPacketReceived(packet.decrypt(this.sessionKey))
is ServerEventPacket.Raw.Encrypted -> onPacketReceived(packet.decrypt(this.sessionKey))
FriendMessageEvent(robot, robot.contacts.getQQ(packet.qq), packet.message)
}
is ServerGroupMessageEventPacket -> {
//todo message chain
//GroupMessageEvent(this.robot, robot.contacts.getGroupByNumber(packet.groupNumber), robot.contacts.getQQ(packet.qq), packet.message)
}
is UnknownServerEventPacket,
is ServerSendFriendMessageResponsePacket,
is ServerSendGroupMessageResponsePacket -> {
//ignored
}
else -> {
//ignored
}
else -> throw IllegalArgumentException(packet.toString())
}
}
internal val packetSystem: PacketSystem = PacketSystem()
inner class PacketSystem {
fun sendFriendMessage(qq: QQ, message: Message) {
TODO()
//sendPacket(ClientSendFriendMessagePacket(robot.account.qqNumber, qq.number, sessionKey, message))
......@@ -360,31 +452,23 @@ internal class RobotNetworkHandler(private val robot: Robot) : Closeable {
TODO()
//sendPacket(ClientSendGroupMessagePacket(group.groupId, robot.account.qqNumber, sessionKey, message))
}
}
/**
* Not async
* 动作: 获取好友列表, 点赞, 踢人等.
* 处理动作事件, 承担动作任务.
*/
@ExperimentalUnsignedTypes
fun sendPacket(packet: ClientPacket) {
try {
packet.encode()
packet.writeHex(Protocol.tail)
inner class ActionHandler : PacketHandler() {
internal lateinit var cookies: String
internal lateinit var sKey: String
internal var gtk: Int = 0
override fun onPacketReceived(packet: ServerPacket) {
val data = packet.toByteArray()
socket.send(DatagramPacket(data, data.size))
MiraiLogger info "Packet sent: $packet"
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun close() {
this.socket.close()
this.loginState = null
this.loginHook = null
this.verificationCodeCache = null
this.tgtgtKey = null
}
}
}
\ No newline at end of file
......@@ -17,6 +17,7 @@ class ClientAccountInfoRequestPacket(
) : ClientPacket() {
override fun encode() {
this.writeRandom(2)//part of packet id
this.writeQQ(qq)
this.writeHex(Protocol.fixVer2)
this.encryptAndWrite(sessionKey) {
......
......@@ -53,11 +53,13 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
551, 487 -> LoginState.DEVICE_LOCK
359 -> LoginState.TAKEN_BACK
else -> LoginState.UNKNOWN
/*
//unknown
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())
else -> throw IllegalArgumentException(bytes.size.toString())*/
}, stream)
}
......@@ -112,17 +114,6 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
}
fun DataInputStream.readUntil(byte: Byte): ByteArray {
var buff = byteArrayOf()
var b: Byte
b = readByte()
while (b != byte) {
buff += b
b = readByte()
}
return buff
}
@ExperimentalUnsignedTypes
fun DataInputStream.readIP(): String {
var buff = ""
......
......@@ -14,5 +14,7 @@ enum class LoginState {
DEVICE_LOCK,//设备锁
TAKEN_BACK,//被回收
// VERIFICATION_CODE,//需要验证码
// SUCCEED,
UNKNOWN,
}
\ No newline at end of file
......@@ -11,9 +11,8 @@ import java.util.Random;
* @author iweiz https://github.com/iweizime/StepChanger/blob/master/app/src/main/java/me/iweizi/stepchanger/qq/Cryptor.java
*/
public final class TEA {
public static final TEA CRYPTOR_SHARE_KEY = new TEA(Protocol.Companion.hexToBytes(Protocol.shareKey));
public static final TEA CRYPTOR_0825KEY = new TEA(Protocol.Companion.hexToBytes(Protocol.key0825));
public static final TEA CRYPTOR_00BAKEY = new TEA(Protocol.Companion.hexToBytes(Protocol.key00BA));
public static final TEA CRYPTOR_SHARE_KEY = new TEA(Protocol.INSTANCE.hexToBytes(Protocol.shareKey));
public static final TEA CRYPTOR_0825KEY = new TEA(Protocol.INSTANCE.hexToBytes(Protocol.key0825));
private static final long UINT32_MASK = 0xffffffffL;
private final long[] mKey;
......
......@@ -79,7 +79,7 @@ operator fun File.plus(child: String): File = File(this, child)
private const val GTK_BASE_VALUE: Int = 5381
fun getGTK(sKey: String): Int {
internal fun getGTK(sKey: String): Int {
var value = GTK_BASE_VALUE
for (c in sKey.toCharArray()) {
value += (value shl 5) + c.toInt()
......@@ -89,7 +89,7 @@ fun getGTK(sKey: String): Int {
return value
}
fun getCrc32(key: ByteArray): Int = CRC32().let { it.update(key); it.value.toInt() }
internal fun getCrc32(key: ByteArray): Int = CRC32().let { it.update(key); it.value.toInt() }
/**
......@@ -122,3 +122,13 @@ fun Any.getAllDeclaredFields(): List<Field> {
return list
}
private const val ZERO_BYTE: Byte = 0
fun ByteArray.removeZeroTail(): ByteArray {
var i = this.size - 1
while (this[i] == ZERO_BYTE) {
--i
}
return this.copyOfRange(0, i + 1)
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment