mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-08 17:20:11 +08:00
Updated network
This commit is contained in:
parent
96a9e6f386
commit
37fa8055b5
@ -185,7 +185,7 @@ internal class BotNetworkHandlerImpl(private val bot: Bot) : BotNetworkHandler {
|
||||
* Not async
|
||||
*/
|
||||
@Synchronized
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun sendPacket(packet: ClientPacket) {
|
||||
checkNotNull(socket) { "network closed" }
|
||||
if (socket!!.isClosed) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
|
||||
package net.mamoe.mirai.network
|
||||
|
||||
import java.net.InetAddress
|
||||
@ -72,7 +74,7 @@ object Protocol {
|
||||
|
||||
private val hexToByteArrayCacheMap: MutableMap<Int, ByteArray> = mutableMapOf()
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun hexToBytes(hex: String): ByteArray {
|
||||
hex.hashCode().let { id ->
|
||||
if (hexToByteArrayCacheMap.containsKey(id)) {
|
||||
@ -86,7 +88,7 @@ object Protocol {
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun hexToUBytes(hex: String): UByteArray = Arrays
|
||||
.stream(hex.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
|
||||
.map { value -> value.trim { it <= ' ' } }
|
||||
|
@ -31,7 +31,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
|
||||
|
||||
private var sKeyRefresherFuture: ScheduledFuture<*>? = null
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun onPacketReceived(packet: ServerPacket) {
|
||||
when (packet) {
|
||||
is ServerCanAddFriendResponsePacket -> {
|
||||
@ -74,12 +74,12 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun addFriend(qqNumber: Long, message: Supplier<String>) {
|
||||
addFriend(qqNumber, lazy { message.get() })
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@JvmSynthetic
|
||||
fun addFriend(qqNumber: Long, message: Lazy<String> = lazyOf("")): CompletableFuture<AddFriendResult> {
|
||||
val future = CompletableFuture<AddFriendResult>()
|
||||
@ -89,12 +89,12 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
|
||||
return future
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun requestSKey() {
|
||||
session.socket.sendPacket(ClientSKeyRequestPacket(session.bot.account.qqNumber, session.sessionKey))
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun requestAccountInfo() {
|
||||
session.socket.sendPacket(ClientAccountInfoRequestPacket(session.bot.account.qqNumber, session.sessionKey))
|
||||
}
|
||||
@ -111,7 +111,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
|
||||
) : Closeable {
|
||||
lateinit var id: ByteArray
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun onPacketReceived(packet: ServerPacket) {
|
||||
if (!::id.isInitialized) {
|
||||
return
|
||||
@ -164,7 +164,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
|
||||
) : Closeable {
|
||||
lateinit var id: ByteArray
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun onPacketReceived(packet: ServerPacket) {
|
||||
if (!::id.isInitialized) {
|
||||
return
|
||||
@ -201,7 +201,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) {
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun sendAddRequest() {
|
||||
session.socket.sendPacket(ClientCanAddFriendPacket(session.bot.account.qqNumber, qq, session.sessionKey).also { this.id = it.packetIdLast })
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ interface DataPacketSocket : Closeable {
|
||||
|
||||
fun distributePacket(packet: ServerPacket)
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun sendPacket(packet: ClientPacket)
|
||||
|
||||
fun isClosed(): Boolean
|
||||
|
@ -74,7 +74,7 @@ class MessagePacketHandler(session: LoginSession) : PacketHandler(session) {
|
||||
session.socket.sendPacket(ClientSendFriendMessagePacket(session.bot.account.qqNumber, qq.number, session.sessionKey, message))
|
||||
}
|
||||
|
||||
fun sendGroupMessage(group: Group, message: Message): Unit {
|
||||
fun sendGroupMessage(group: Group, message: Message) {
|
||||
TODO()
|
||||
//sendPacket(ClientSendGroupMessagePacket(group.groupId, bot.account.qqNumber, sessionKey, message))
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
|
||||
|
||||
package net.mamoe.mirai.network.packet
|
||||
|
||||
import lombok.Getter
|
||||
@ -12,12 +14,12 @@ import java.security.MessageDigest
|
||||
/**
|
||||
* @author Him188moe
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
|
||||
@Getter
|
||||
val idHex: String
|
||||
|
||||
var encoded: Boolean = false
|
||||
private var encoded: Boolean = false
|
||||
|
||||
init {
|
||||
val annotation = this.javaClass.getAnnotation(PacketId::class.java)
|
||||
@ -84,7 +86,6 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
|
||||
}
|
||||
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeIP(ip: String) {
|
||||
for (s in ip.trim().split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
|
||||
@ -97,10 +98,9 @@ fun DataOutputStream.writeTime() {
|
||||
this.writeInt(System.currentTimeMillis().toInt())
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeHex(hex: String) {
|
||||
for (s in hex.trim().split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
|
||||
fun DataOutputStream.writeHex(uHex: String) {
|
||||
for (s in uHex.trim().split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
|
||||
if (s.isEmpty()) {
|
||||
continue
|
||||
}
|
||||
@ -116,12 +116,10 @@ fun DataOutputStream.encryptAndWrite(key: ByteArray, encoder: (ByteArrayDataOutp
|
||||
this.write(TEA.encrypt(ByteArrayDataOutputStream().also(encoder).toByteArray(), key))
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun DataOutputStream.encryptAndWrite(keyHex: String, encoder: (ByteArrayDataOutputStream) -> Unit) {
|
||||
this.encryptAndWrite(keyHex.hexToBytes(), encoder)
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeTLV0006(qq: Long, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray) {
|
||||
ByteArrayDataOutputStream().let {
|
||||
@ -146,12 +144,10 @@ fun DataOutputStream.writeTLV0006(qq: Long, password: String, loginTime: Int, lo
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
@TestedSuccessfully
|
||||
@Tested
|
||||
fun DataOutputStream.writeCRC32() = writeCRC32(getRandomByteArray(16))
|
||||
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun DataOutputStream.writeCRC32(key: ByteArray) {
|
||||
key.let {
|
||||
write(it)//key
|
||||
@ -159,8 +155,8 @@ fun DataOutputStream.writeCRC32(key: ByteArray) {
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
@TestedSuccessfully
|
||||
|
||||
@Tested
|
||||
fun DataOutputStream.writeDeviceName(random: Boolean = false) {
|
||||
val deviceName: String = if (random) {
|
||||
String(getRandomByteArray(10))
|
||||
@ -185,7 +181,7 @@ fun Int.toByteArray(): ByteArray = byteArrayOf(
|
||||
/**
|
||||
* 255u -> 00 00 00 FF
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun UInt.toByteArray(): ByteArray = byteArrayOf(
|
||||
(this.shr(24) and 255u).toByte(),
|
||||
(this.shr(16) and 255u).toByte(),
|
||||
@ -193,24 +189,14 @@ fun UInt.toByteArray(): ByteArray = byteArrayOf(
|
||||
(this.shr(0) and 255u).toByte()
|
||||
)
|
||||
|
||||
/**
|
||||
* 255 -> FF 00 00 00
|
||||
*/
|
||||
fun Int.toLByteArray(): ByteArray = byteArrayOf(
|
||||
(this.ushr(0) and 0xFF).toByte(),
|
||||
(this.ushr(8) and 0xFF).toByte(),
|
||||
(this.ushr(16) and 0xFF).toByte(),
|
||||
(this.ushr(24) and 0xFF).toByte()
|
||||
)
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun Int.toUHexString(separator: String = " "): String = this.toByteArray().toUHexString(separator)
|
||||
|
||||
internal fun md5(str: String): ByteArray = MessageDigest.getInstance("MD5").digest(str.toByteArray())
|
||||
|
||||
internal fun md5(byteArray: ByteArray): ByteArray = MessageDigest.getInstance("MD5").digest(byteArray)
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeZero(count: Int) {
|
||||
repeat(count) {
|
||||
@ -225,13 +211,13 @@ fun DataOutputStream.writeRandom(length: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeQQ(qq: Long) {
|
||||
this.write(qq.toUInt().toByteArray())
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeGroup(groupIdOrGroupNumber: Long) {
|
||||
this.write(groupIdOrGroupNumber.toUInt().toByteArray())
|
||||
|
@ -9,7 +9,7 @@ import java.io.DataInputStream
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@PacketId("00 5C")
|
||||
class ClientAccountInfoRequestPacket(
|
||||
private val qq: Long,
|
||||
|
@ -7,7 +7,7 @@ import java.io.IOException
|
||||
/**
|
||||
* @author Him188moe
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@PacketId("00 58")
|
||||
class ClientHeartbeatPacket(
|
||||
private val qq: Long,
|
||||
|
@ -10,7 +10,7 @@ import java.io.DataInputStream
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@PacketId("00 1D")
|
||||
class ClientSKeyRequestPacket(
|
||||
private val qq: Long,
|
||||
@ -31,7 +31,7 @@ class ClientSKeyRequestPacket(
|
||||
* @author Him188moe
|
||||
*/
|
||||
@PacketId("00 1D")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientSKeyRefreshmentRequestPacket(
|
||||
private val qq: Long,
|
||||
private val sessionKey: ByteArray
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
|
||||
package net.mamoe.mirai.network.packet
|
||||
|
||||
import net.mamoe.mirai.message.FaceID
|
||||
@ -22,7 +24,7 @@ import java.util.zip.GZIPInputStream
|
||||
abstract class ServerEventPacket(input: DataInputStream, val packetId: ByteArray, val eventIdentity: ByteArray) : ServerPacket(input) {
|
||||
@PacketId("00 17")
|
||||
class Raw(input: DataInputStream, private val packetId: ByteArray) : ServerPacket(input) {
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun distribute(): ServerEventPacket {
|
||||
val eventIdentity = this.input.readNBytes(16)
|
||||
val type = this.input.goto(18).readNBytes(2)
|
||||
@ -80,6 +82,7 @@ class ServerGroupUploadFileEventPacket(input: DataInputStream, packetId: ByteArr
|
||||
}//todo test
|
||||
}
|
||||
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray, eventIdentity: ByteArray) : ServerEventPacket(input, packetId, eventIdentity) {
|
||||
var groupNumber: Long = 0
|
||||
var qq: Long = 0
|
||||
@ -100,16 +103,16 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
|
||||
OTHER,
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun decode() {
|
||||
groupNumber = this.input.goto(51).readInt().toLong()
|
||||
qq = this.input.goto(56).readLong().toUInt().toLong()
|
||||
qq = this.input.goto(56).readLong()
|
||||
val fontLength = this.input.goto(108).readShort()
|
||||
//println(this.input.goto(110 + fontLength).readNBytesAt(2).toUHexString())//always 00 00
|
||||
|
||||
messageType = when (val id = this.input.goto(110 + fontLength + 2).readByte().toInt()) {
|
||||
0x13 -> MessageType.NORMAL
|
||||
0xE -> MessageType.XML
|
||||
0x0E -> MessageType.XML
|
||||
0x06 -> MessageType.AT
|
||||
|
||||
|
||||
@ -188,7 +191,7 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
|
||||
var qq: Long = 0
|
||||
lateinit var message: MessageChain
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun decode() {
|
||||
input.goto(0)
|
||||
println()
|
||||
@ -291,7 +294,7 @@ B1 89 BE 09 8F 00 1A E5 00 0B 03 A2 09 90 BB 7A 1F 40 00 A6 00 00 00 20 00 05 00
|
||||
* 告知服务器已经收到数据
|
||||
*/
|
||||
@PacketId("")//随后写入
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientMessageResponsePacket(
|
||||
private val qq: Long,
|
||||
private val packetIdFromServer: ByteArray,//4bytes
|
||||
@ -329,7 +332,7 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
|
||||
lateinit var message: String
|
||||
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun decode() {
|
||||
//start at Sep1.0:27
|
||||
qq = input.readIntAt(0)
|
||||
|
@ -2,7 +2,6 @@ package net.mamoe.mirai.network.packet
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
import net.mamoe.mirai.utils.TEA
|
||||
import net.mamoe.mirai.utils.getRandomByteArray
|
||||
import net.mamoe.mirai.utils.lazyEncode
|
||||
import java.io.DataInputStream
|
||||
import java.net.InetAddress
|
||||
@ -10,7 +9,7 @@ import java.net.InetAddress
|
||||
/**
|
||||
* @author Him188moe
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@PacketId("08 28 04 34")
|
||||
class ClientSessionRequestPacket(
|
||||
private val qq: Long,
|
||||
@ -48,12 +47,12 @@ class ClientSessionRequestPacket(
|
||||
|
||||
it.writeHex("01 0B 00 85 00 02")
|
||||
it.writeHex("B9 ED EF D7 CD E5 47 96 7A B5 28 34 CA 93 6B 5C")//fix2
|
||||
it.write(getRandomByteArray(1))
|
||||
it.writeRandom(1)
|
||||
it.writeHex("10 00 00 00 00 00 00 00 02")
|
||||
|
||||
//fix3
|
||||
it.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")
|
||||
it.write(getRandomByteArray(32))//md5 32
|
||||
it.writeRandom(32)//md5 32
|
||||
it.writeHex("68")
|
||||
|
||||
it.writeHex("00 00 00 00 00 2D 00 06 00 01")
|
||||
@ -70,7 +69,7 @@ class ServerSessionKeyResponsePacket(inputStream: DataInputStream, private val d
|
||||
lateinit var sessionKey: ByteArray
|
||||
lateinit var tlv0105: ByteArray
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun decode() {
|
||||
when (dataLength) {
|
||||
407 -> {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.mamoe.mirai.network.packet
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
import net.mamoe.mirai.network.packet.login.ClientPasswordSubmissionPacket
|
||||
import net.mamoe.mirai.utils.ByteArrayDataOutputStream
|
||||
import net.mamoe.mirai.utils.TEA
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
@ -11,11 +12,12 @@ import java.io.IOException
|
||||
/**
|
||||
* A packet received when logging in, used to redirect server address
|
||||
*
|
||||
* @see net.mamoe.mirai.network.packet.client.login.ClientServerRedirectionPacket
|
||||
* @see net.mamoe.mirai.network.packet.client.login.ClientPasswordSubmissionPacket
|
||||
* @see ClientServerRedirectionPacket
|
||||
* @see ClientPasswordSubmissionPacket
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
@PacketId("08 25 31 01")
|
||||
class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) {
|
||||
var serverIP: String? = null
|
||||
@ -29,9 +31,9 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
|
||||
TYPE_08_25_31_02,
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun decode() {
|
||||
when (val id = input.readByte().toUByte().toInt()) {
|
||||
when (val id = input.readByte().toInt()) {
|
||||
0xFE -> {
|
||||
input.skip(94)
|
||||
serverIP = input.readIP()
|
||||
@ -52,7 +54,7 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
|
||||
}
|
||||
|
||||
class Encrypted(private val type: Type, inputStream: DataInputStream) : ServerPacket(inputStream) {
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun decrypt(): ServerTouchResponsePacket = ServerTouchResponsePacket(decryptBy(when (type) {
|
||||
Type.TYPE_08_25_31_02 -> Protocol.redirectionKey.hexToBytes()
|
||||
Type.TYPE_08_25_31_01 -> Protocol.key0825.hexToBytes()
|
||||
@ -65,10 +67,10 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@PacketId("08 25 31 01")
|
||||
class ClientTouchPacket(private val qq: Long, private val serverIp: String) : ClientPacket() {
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun encode() {
|
||||
this.writeQQ(qq)
|
||||
@ -80,7 +82,7 @@ class ClientTouchPacket(private val qq: Long, private val serverIp: String) : Cl
|
||||
it.writeHex(Protocol.constantData2)
|
||||
it.writeQQ(qq)
|
||||
it.writeHex("00 00 00 00 03 09 00 08 00 01")
|
||||
it.writeIP(serverIp);
|
||||
it.writeIP(serverIp)
|
||||
it.writeHex("00 02 00 36 00 12 00 02 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 14 00 1D 01 02 00 19")
|
||||
it.writeHex(Protocol.publicKey)
|
||||
}
|
||||
@ -92,10 +94,10 @@ class ClientTouchPacket(private val qq: Long, private val serverIp: String) : Cl
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@PacketId("08 25 31 02")
|
||||
class ClientServerRedirectionPacket(private val serverIP: String, private val qq: Long) : ClientPacket() {
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun encode() {
|
||||
this.writeQQ(qq)
|
||||
this.writeHex(Protocol.fixVer)
|
||||
|
@ -2,14 +2,14 @@ package net.mamoe.mirai.network.packet
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
import net.mamoe.mirai.utils.TEA
|
||||
import net.mamoe.mirai.utils.TestedSuccessfully
|
||||
import net.mamoe.mirai.utils.Tested
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
import java.io.DataInputStream
|
||||
|
||||
/**
|
||||
* 客户端请求验证码图片数据的第几部分
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@PacketId("00 BA 31")
|
||||
class ClientVerificationCodeTransmissionRequestPacket(
|
||||
private val packetId: Int,
|
||||
@ -18,7 +18,7 @@ class ClientVerificationCodeTransmissionRequestPacket(
|
||||
private val verificationSequence: Int,
|
||||
private val token00BA: ByteArray
|
||||
) : ClientPacket() {
|
||||
@TestedSuccessfully
|
||||
@Tested
|
||||
override fun encode() {
|
||||
this.writeByte(packetId)//part of packet id
|
||||
|
||||
@ -46,7 +46,7 @@ class ClientVerificationCodeTransmissionRequestPacket(
|
||||
* 提交验证码
|
||||
*/
|
||||
@PacketId("00 BA 32")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientVerificationCodeSubmitPacket(
|
||||
private val packetIdLast: Int,
|
||||
private val qq: Long,
|
||||
@ -93,7 +93,7 @@ class ClientVerificationCodeSubmitPacket(
|
||||
* 刷新验证码
|
||||
*/
|
||||
@PacketId("00 BA 31")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientVerificationCodeRefreshPacket(
|
||||
private val packetIdLast: Int,
|
||||
private val qq: Long,
|
||||
@ -142,7 +142,7 @@ open class ServerVerificationCodeTransmissionPacket(input: DataInputStream, priv
|
||||
lateinit var token00BA: ByteArray//40 bytes
|
||||
var packetIdLast: Int = 0
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun decode() {
|
||||
this.verificationToken = this.input.readNBytesAt(10, 56)
|
||||
|
||||
@ -181,7 +181,7 @@ class ServerVerificationCodeCorrectPacket(input: DataInputStream) : ServerVerifi
|
||||
|
||||
lateinit var token00BA: ByteArray//56 bytes
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun decode() {
|
||||
token00BA = this.input.readNBytesAt(10, 56)
|
||||
}
|
||||
@ -191,7 +191,7 @@ abstract class ServerVerificationCodePacket(input: DataInputStream) : ServerPack
|
||||
|
||||
@PacketId("00 BA")
|
||||
class Encrypted(input: DataInputStream, private val id: String) : ServerPacket(input) {
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun decrypt(): ServerVerificationCodePacket {
|
||||
this.input goto 14
|
||||
val data = TEA.decrypt(this.input.readAllBytes().cutTail(1), Protocol.key00BA.hexToBytes())
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
|
||||
|
||||
package net.mamoe.mirai.network.packet.action
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
@ -13,7 +15,7 @@ import java.util.*
|
||||
* @author Him188moe
|
||||
*/
|
||||
@PacketId("00 A7")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientCanAddFriendPacket(
|
||||
val bot: Long,
|
||||
val qq: Long,
|
||||
@ -47,7 +49,7 @@ class ServerCanAddFriendResponsePacket(input: DataInputStream) : ServerPacket(in
|
||||
FAILED,
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun decode() {
|
||||
val data = input.goto(0).readAllBytes()
|
||||
if (data.size == 99) {
|
||||
@ -78,7 +80,7 @@ class ServerCanAddFriendResponsePacket(input: DataInputStream) : ServerPacket(in
|
||||
* 请求添加好友
|
||||
*/
|
||||
@PacketId("00 AE")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientAddFriendPacket(
|
||||
val bot: Long,
|
||||
val qq: Long,
|
||||
|
@ -10,7 +10,7 @@ import java.io.DataInputStream
|
||||
* @author Him188moe
|
||||
*/
|
||||
@PacketId("00 CD")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientSendFriendMessagePacket(
|
||||
private val botQQ: Long,
|
||||
private val targetQQ: Long,
|
||||
|
@ -9,7 +9,7 @@ import java.io.DataInputStream
|
||||
* @author Him188moe
|
||||
*/
|
||||
@PacketId("00 02")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientSendGroupMessagePacket(
|
||||
private val groupId: Long,//不是 number
|
||||
private val botQQ: Long,
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
|
||||
|
||||
package net.mamoe.mirai.network.packet.image
|
||||
|
||||
import net.mamoe.mirai.network.packet.*
|
||||
@ -15,7 +17,7 @@ import java.io.DataInputStream
|
||||
* @author Him188moe
|
||||
*/
|
||||
@PacketId("03 88")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientTryGetGroupImageIDPacket(
|
||||
private val bot: Long,
|
||||
private val sessionKey: ByteArray,
|
||||
@ -108,7 +110,7 @@ abstract class ServerTryUploadGroupImageResponsePacket(input: DataInputStream) :
|
||||
class ServerTryUploadGroupImageSuccessPacket(input: DataInputStream) : ServerTryUploadGroupImageResponsePacket(input) {
|
||||
lateinit var uKey: ByteArray
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun decode() {
|
||||
uKey = this.input.gotoWhere(ubyteArrayOf(0x42u, 0x80u, 0x01u)).readNBytes(128)
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import net.mamoe.mirai.utils.ClientLoginStatus
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@PacketId("00 EC")
|
||||
class ClientChangeOnlineStatusPacket(
|
||||
private val qq: Long,
|
||||
|
@ -4,7 +4,7 @@ import net.mamoe.mirai.network.Protocol
|
||||
import net.mamoe.mirai.network.packet.*
|
||||
import net.mamoe.mirai.utils.ByteArrayDataOutputStream
|
||||
import net.mamoe.mirai.utils.TEA
|
||||
import net.mamoe.mirai.utils.TestedSuccessfully
|
||||
import net.mamoe.mirai.utils.Tested
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
import java.io.DataOutputStream
|
||||
|
||||
@ -14,8 +14,8 @@ import java.io.DataOutputStream
|
||||
* @author Him188moe
|
||||
*/
|
||||
@PacketId("08 36 31 03")
|
||||
@ExperimentalUnsignedTypes
|
||||
@TestedSuccessfully
|
||||
|
||||
@Tested
|
||||
class ClientPasswordSubmissionPacket(
|
||||
private val qq: Long,
|
||||
private val password: String,
|
||||
@ -24,7 +24,7 @@ class ClientPasswordSubmissionPacket(
|
||||
private val tgtgtKey: ByteArray,
|
||||
private val token0825: ByteArray
|
||||
) : ClientPacket() {
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
override fun encode() {
|
||||
this.writeQQ(qq)
|
||||
this.writeHex(Protocol.passwordSubmissionKey1)
|
||||
@ -40,21 +40,21 @@ class ClientPasswordSubmissionPacket(
|
||||
}
|
||||
|
||||
@PacketId("08 36 31 04")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientLoginResendPacket3104(qq: Long, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray, tlv0006: ByteArray? = null)
|
||||
: ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA, tlv0006)
|
||||
|
||||
@PacketId("08 36 31 05")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientLoginResendPacket3105(qq: Long, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray)
|
||||
: ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA, null)
|
||||
|
||||
@PacketId("08 36 31 06")
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
class ClientLoginResendPacket3106(qq: Long, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray, tlv0006: ByteArray? = null)
|
||||
: ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA, tlv0006)
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
open class ClientLoginResendPacket internal constructor(
|
||||
val qq: Long,
|
||||
val password: String,
|
||||
@ -93,7 +93,7 @@ open class ClientLoginResendPacket internal constructor(
|
||||
/**
|
||||
* @author Him188moe
|
||||
*/
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
private fun DataOutputStream.writePart1(qq: Long, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, tlv0006: ByteArray? = null) {
|
||||
|
||||
//this.writeInt(System.currentTimeMillis().toInt())
|
||||
@ -130,7 +130,7 @@ private fun DataOutputStream.writePart1(qq: Long, password: String, loginTime: I
|
||||
this.writeHex("60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6")//key
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
private fun DataOutputStream.writePart2() {
|
||||
|
||||
this.writeHex("03 12")//tag
|
||||
|
@ -4,7 +4,7 @@ import net.mamoe.mirai.network.Protocol
|
||||
import net.mamoe.mirai.network.packet.PacketId
|
||||
import net.mamoe.mirai.network.packet.ServerPacket
|
||||
import net.mamoe.mirai.network.packet.goto
|
||||
import net.mamoe.mirai.utils.TestedSuccessfully
|
||||
import net.mamoe.mirai.utils.Tested
|
||||
import java.io.DataInputStream
|
||||
|
||||
/**
|
||||
@ -23,7 +23,7 @@ class ServerLoginResponseKeyExchangePacket(input: DataInputStream, val flag: Fla
|
||||
var tokenUnknown: ByteArray? = null
|
||||
lateinit var tgtgtKey: ByteArray//16bytes
|
||||
|
||||
@TestedSuccessfully
|
||||
@Tested
|
||||
override fun decode() {
|
||||
this.input.skip(5)
|
||||
tgtgtKey = this.input.readNBytes(16)//22
|
||||
@ -46,8 +46,8 @@ class ServerLoginResponseKeyExchangePacket(input: DataInputStream, val flag: Fla
|
||||
}
|
||||
|
||||
class Encrypted(input: DataInputStream, private val flag: Flag) : ServerPacket(input) {
|
||||
@ExperimentalUnsignedTypes
|
||||
@TestedSuccessfully
|
||||
|
||||
@Tested
|
||||
fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseKeyExchangePacket {
|
||||
return ServerLoginResponseKeyExchangePacket(this.decryptBy(Protocol.shareKey, tgtgtKey), flag).setId(this.idHex)
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
|
||||
package net.mamoe.mirai.network.packet.login
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
@ -5,7 +7,7 @@ import net.mamoe.mirai.network.packet.ServerPacket
|
||||
import net.mamoe.mirai.network.packet.goto
|
||||
import net.mamoe.mirai.network.packet.readNBytesAt
|
||||
import net.mamoe.mirai.network.packet.readString
|
||||
import net.mamoe.mirai.utils.TestedSuccessfully
|
||||
import net.mamoe.mirai.utils.Tested
|
||||
import net.mamoe.mirai.utils.toUHexString
|
||||
import java.io.DataInputStream
|
||||
|
||||
@ -21,8 +23,8 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
|
||||
lateinit var encryptionKey: ByteArray
|
||||
|
||||
|
||||
@TestedSuccessfully
|
||||
@ExperimentalUnsignedTypes
|
||||
@Tested
|
||||
|
||||
override fun decode() {
|
||||
this.input.skip(7)//8
|
||||
this.encryptionKey = this.input.readNBytes(16)//24
|
||||
@ -52,7 +54,7 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
|
||||
|
||||
|
||||
class Encrypted(input: DataInputStream) : ServerPacket(input) {
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseSuccessPacket {
|
||||
input goto 14
|
||||
return ServerLoginResponseSuccessPacket(this.decryptBy(Protocol.shareKey, tgtgtKey)).setId(this.idHex)
|
||||
|
@ -1,10 +1,12 @@
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
|
||||
package net.mamoe.mirai.network.packet.login
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
import net.mamoe.mirai.network.packet.ServerPacket
|
||||
import net.mamoe.mirai.network.packet.dataInputStream
|
||||
import net.mamoe.mirai.network.packet.goto
|
||||
import net.mamoe.mirai.utils.TestedSuccessfully
|
||||
import net.mamoe.mirai.utils.Tested
|
||||
import net.mamoe.mirai.utils.hexToUBytes
|
||||
import java.io.DataInputStream
|
||||
|
||||
@ -20,8 +22,8 @@ class ServerLoginResponseVerificationCodeInitPacket(input: DataInputStream, priv
|
||||
var unknownBoolean: Boolean? = null
|
||||
|
||||
|
||||
@TestedSuccessfully
|
||||
@ExperimentalUnsignedTypes
|
||||
@Tested
|
||||
|
||||
override fun decode() {
|
||||
val verifyCodeLength = this.input.goto(78).readShort()//2bytes
|
||||
this.verifyCodePart1 = this.input.readNBytes(verifyCodeLength.toInt())
|
||||
@ -39,7 +41,7 @@ class ServerLoginResponseVerificationCodeInitPacket(input: DataInputStream, priv
|
||||
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun decrypt(): ServerLoginResponseVerificationCodeInitPacket {
|
||||
this.input goto 14
|
||||
val data = this.decryptBy(Protocol.shareKey).goto(0).readAllBytes()
|
||||
|
@ -1,277 +1,269 @@
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.*
|
||||
import kotlin.experimental.and
|
||||
import kotlin.experimental.xor
|
||||
|
||||
/**
|
||||
* @author Him188moe
|
||||
*/
|
||||
/**
|
||||
* TEA 加密
|
||||
*
|
||||
* @author iweiz https://github.com/iweizime/StepChanger/blob/master/app/src/main/java/me/iweizi/stepchanger/qq/Cryptor.java
|
||||
*/
|
||||
class TEA(private val key: ByteArray) {
|
||||
object TEA {
|
||||
private const val UINT32_MASK = 0xffffffffL
|
||||
|
||||
private fun doOption(data: ByteArray, key: ByteArray, encrypt: Boolean): ByteArray {
|
||||
val mRandom = Random()
|
||||
lateinit var mOutput: ByteArray
|
||||
lateinit var mInBlock: ByteArray
|
||||
var mIndexPos: Int
|
||||
lateinit var mIV: ByteArray
|
||||
var mOutPos = 0
|
||||
var mPreOutPos = 0
|
||||
var isFirstBlock = true
|
||||
|
||||
companion object {
|
||||
val CRYPTOR_SHARE_KEY = TEA(Protocol.hexToBytes(Protocol.shareKey))
|
||||
val CRYPTOR_0825KEY = TEA(Protocol.hexToBytes(Protocol.key0825))
|
||||
val mKey = LongArray(4)
|
||||
|
||||
private val UINT32_MASK = 0xffffffffL
|
||||
for (i in 0..3) {
|
||||
mKey[i] = pack(key, i * 4, 4)
|
||||
}
|
||||
|
||||
fun doOption(data: ByteArray, key: ByteArray, encrypt: Boolean): ByteArray {
|
||||
val mRandom = Random()
|
||||
lateinit var mOutput: ByteArray
|
||||
lateinit var mInBlock: ByteArray
|
||||
var mIndexPos: Int
|
||||
lateinit var mIV: ByteArray
|
||||
var mOutPos = 0
|
||||
var mPreOutPos = 0
|
||||
var isFirstBlock: Boolean = true
|
||||
fun rand(): Int {
|
||||
return mRandom.nextInt()
|
||||
}
|
||||
|
||||
val mKey = LongArray(4)
|
||||
fun encode(bytes: ByteArray): ByteArray {
|
||||
var v0 = pack(bytes, 0, 4)
|
||||
var v1 = pack(bytes, 4, 4)
|
||||
var sum: Long = 0
|
||||
val delta = 0x9e3779b9L
|
||||
for (i in 0..15) {
|
||||
sum = sum + delta and UINT32_MASK
|
||||
v0 += (v1 shl 4) + mKey[0] xor v1 + sum xor v1.ushr(5) + mKey[1]
|
||||
v0 = v0 and UINT32_MASK
|
||||
v1 += (v0 shl 4) + mKey[2] xor v0 + sum xor v0.ushr(5) + mKey[3]
|
||||
v1 = v1 and UINT32_MASK
|
||||
}
|
||||
return ByteBuffer.allocate(8).putInt(v0.toInt()).putInt(v1.toInt()).array()
|
||||
}
|
||||
|
||||
for (i in 0..3) {
|
||||
mKey[i] = pack(key, i * 4, 4)
|
||||
fun decode(bytes: ByteArray, offset: Int): ByteArray {
|
||||
var v0 = pack(bytes, offset, 4)
|
||||
var v1 = pack(bytes, offset + 4, 4)
|
||||
val delta = 0x9e3779b9L
|
||||
var sum = delta shl 4 and UINT32_MASK
|
||||
for (i in 0..15) {
|
||||
v1 -= (v0 shl 4) + mKey[2] xor v0 + sum xor v0.ushr(5) + mKey[3]
|
||||
v1 = v1 and UINT32_MASK
|
||||
v0 -= (v1 shl 4) + mKey[0] xor v1 + sum xor v1.ushr(5) + mKey[1]
|
||||
v0 = v0 and UINT32_MASK
|
||||
sum = sum - delta and UINT32_MASK
|
||||
}
|
||||
return ByteBuffer.allocate(8).putInt(v0.toInt()).putInt(v1.toInt()).array()
|
||||
}
|
||||
|
||||
fun encodeOneBlock() {
|
||||
mIndexPos = 0
|
||||
while (mIndexPos < 8) {
|
||||
mInBlock[mIndexPos] = if (isFirstBlock)
|
||||
mInBlock[mIndexPos]
|
||||
else
|
||||
(mInBlock[mIndexPos] xor mOutput[mPreOutPos + mIndexPos])
|
||||
mIndexPos++
|
||||
}
|
||||
|
||||
fun rand(): Int {
|
||||
return mRandom.nextInt()
|
||||
System.arraycopy(encode(mInBlock), 0, mOutput, mOutPos, 8)
|
||||
mIndexPos = 0
|
||||
while (mIndexPos < 8) {
|
||||
val outPos = mOutPos + mIndexPos
|
||||
mOutput[outPos] = (mOutput[outPos] xor mIV[mIndexPos])
|
||||
mIndexPos++
|
||||
}
|
||||
System.arraycopy(mInBlock, 0, mIV, 0, 8)
|
||||
mPreOutPos = mOutPos
|
||||
mOutPos += 8
|
||||
mIndexPos = 0
|
||||
isFirstBlock = false
|
||||
}
|
||||
|
||||
fun encode(bytes: ByteArray): ByteArray {
|
||||
var v0 = pack(bytes, 0, 4)
|
||||
var v1 = pack(bytes, 4, 4)
|
||||
var sum: Long = 0
|
||||
val delta = 0x9e3779b9L
|
||||
for (i in 0..15) {
|
||||
sum = sum + delta and UINT32_MASK
|
||||
v0 += (v1 shl 4) + mKey[0] xor v1 + sum xor v1.ushr(5) + mKey[1]
|
||||
v0 = v0 and UINT32_MASK
|
||||
v1 += (v0 shl 4) + mKey[2] xor v0 + sum xor v0.ushr(5) + mKey[3]
|
||||
v1 = v1 and UINT32_MASK
|
||||
}
|
||||
return ByteBuffer.allocate(8).putInt(v0.toInt()).putInt(v1.toInt()).array()
|
||||
}
|
||||
|
||||
fun decode(bytes: ByteArray, offset: Int): ByteArray {
|
||||
var v0 = pack(bytes, offset, 4)
|
||||
var v1 = pack(bytes, offset + 4, 4)
|
||||
val delta = 0x9e3779b9L
|
||||
var sum = delta shl 4 and UINT32_MASK
|
||||
for (i in 0..15) {
|
||||
v1 -= (v0 shl 4) + mKey[2] xor v0 + sum xor v0.ushr(5) + mKey[3]
|
||||
v1 = v1 and UINT32_MASK
|
||||
v0 -= (v1 shl 4) + mKey[0] xor v1 + sum xor v1.ushr(5) + mKey[1]
|
||||
v0 = v0 and UINT32_MASK
|
||||
sum = sum - delta and UINT32_MASK
|
||||
}
|
||||
return ByteBuffer.allocate(8).putInt(v0.toInt()).putInt(v1.toInt()).array()
|
||||
}
|
||||
|
||||
fun encodeOneBlock() {
|
||||
mIndexPos = 0
|
||||
while (mIndexPos < 8) {
|
||||
mInBlock[mIndexPos] = if (isFirstBlock)
|
||||
mInBlock[mIndexPos]
|
||||
else
|
||||
(mInBlock[mIndexPos] xor mOutput[mPreOutPos + mIndexPos])
|
||||
fun decodeOneBlock(ciphertext: ByteArray, offset: Int, len: Int): Boolean {
|
||||
mIndexPos = 0
|
||||
while (mIndexPos < 8) {
|
||||
if (mOutPos + mIndexPos < len) {
|
||||
mIV[mIndexPos] = (mIV[mIndexPos] xor ciphertext[mOutPos + offset + mIndexPos])
|
||||
mIndexPos++
|
||||
continue
|
||||
}
|
||||
|
||||
System.arraycopy(encode(mInBlock), 0, mOutput, mOutPos, 8)
|
||||
mIndexPos = 0
|
||||
while (mIndexPos < 8) {
|
||||
val out_pos = mOutPos + mIndexPos
|
||||
mOutput[out_pos] = (mOutput[out_pos] xor mIV[mIndexPos])
|
||||
mIndexPos++
|
||||
}
|
||||
System.arraycopy(mInBlock, 0, mIV, 0, 8)
|
||||
mPreOutPos = mOutPos
|
||||
mOutPos += 8
|
||||
mIndexPos = 0
|
||||
isFirstBlock = false
|
||||
}
|
||||
|
||||
fun decodeOneBlock(ciphertext: ByteArray, offset: Int, len: Int): Boolean {
|
||||
mIndexPos = 0
|
||||
while (mIndexPos < 8) {
|
||||
if (mOutPos + mIndexPos < len) {
|
||||
mIV[mIndexPos] = (mIV[mIndexPos] xor ciphertext[mOutPos + offset + mIndexPos])
|
||||
mIndexPos++
|
||||
continue
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
mIV = decode(mIV, 0)
|
||||
mOutPos += 8
|
||||
mIndexPos = 0
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
fun encrypt(plaintext: ByteArray, offset: Int, len: Int): ByteArray {
|
||||
var len = len;
|
||||
var offset = offset;
|
||||
mInBlock = ByteArray(8)
|
||||
mIV = ByteArray(8)
|
||||
mOutPos = 0
|
||||
mPreOutPos = 0
|
||||
isFirstBlock = true
|
||||
mIndexPos = (len + 10) % 8
|
||||
if (mIndexPos != 0) {
|
||||
mIndexPos = 8 - mIndexPos
|
||||
}
|
||||
mOutput = ByteArray(mIndexPos + len + 10)
|
||||
mInBlock[0] = (rand() and 0xf8 or mIndexPos).toByte()
|
||||
for (i in 1..mIndexPos) {
|
||||
mInBlock[i] = (rand() and 0xff).toByte()
|
||||
}
|
||||
++mIndexPos
|
||||
for (i in 0..7) {
|
||||
mIV[i] = 0
|
||||
}
|
||||
mIV = decode(mIV, 0)
|
||||
mOutPos += 8
|
||||
mIndexPos = 0
|
||||
return true
|
||||
|
||||
var g = 0
|
||||
while (g < 2) {
|
||||
if (mIndexPos < 8) {
|
||||
mInBlock[mIndexPos++] = (rand() and 0xff).toByte()
|
||||
++g
|
||||
}
|
||||
if (mIndexPos == 8) {
|
||||
encodeOneBlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
if (mIndexPos < 8) {
|
||||
mInBlock[mIndexPos++] = plaintext[offset++]
|
||||
}
|
||||
if (mIndexPos == 8) {
|
||||
encodeOneBlock()
|
||||
}
|
||||
len--
|
||||
}
|
||||
g = 0
|
||||
while (g < 7) {
|
||||
if (mIndexPos < 8) {
|
||||
mInBlock[mIndexPos++] = 0.toByte()
|
||||
}
|
||||
if (mIndexPos == 8) {
|
||||
encodeOneBlock()
|
||||
}
|
||||
g++
|
||||
}
|
||||
return mOutput
|
||||
@Suppress("NAME_SHADOWING")
|
||||
fun encrypt(plaintext: ByteArray, offset: Int, len: Int): ByteArray {
|
||||
var len = len
|
||||
var offset = offset
|
||||
mInBlock = ByteArray(8)
|
||||
mIV = ByteArray(8)
|
||||
mOutPos = 0
|
||||
mPreOutPos = 0
|
||||
isFirstBlock = true
|
||||
mIndexPos = (len + 10) % 8
|
||||
if (mIndexPos != 0) {
|
||||
mIndexPos = 8 - mIndexPos
|
||||
}
|
||||
mOutput = ByteArray(mIndexPos + len + 10)
|
||||
mInBlock[0] = (rand() and 0xf8 or mIndexPos).toByte()
|
||||
for (i in 1..mIndexPos) {
|
||||
mInBlock[i] = (rand() and 0xff).toByte()
|
||||
}
|
||||
++mIndexPos
|
||||
for (i in 0..7) {
|
||||
mIV[i] = 0
|
||||
}
|
||||
|
||||
fun decrypt(cipherText: ByteArray, offset: Int, len: Int): ByteArray? {
|
||||
require(!(len % 8 != 0 || len < 16)) { "must len % 8 == 0 && len >= 16" }
|
||||
mIV = decode(cipherText, offset)
|
||||
mIndexPos = (mIV[0] and 7).toInt()
|
||||
var plen = len - mIndexPos - 10
|
||||
isFirstBlock = true
|
||||
if (plen < 0) {
|
||||
return null
|
||||
var g = 0
|
||||
while (g < 2) {
|
||||
if (mIndexPos < 8) {
|
||||
mInBlock[mIndexPos++] = (rand() and 0xff).toByte()
|
||||
++g
|
||||
}
|
||||
mOutput = ByteArray(plen)
|
||||
mPreOutPos = 0
|
||||
mOutPos = 8
|
||||
++mIndexPos
|
||||
var g = 0
|
||||
while (g < 2) {
|
||||
if (mIndexPos < 8) {
|
||||
++mIndexPos
|
||||
++g
|
||||
}
|
||||
if (mIndexPos == 8) {
|
||||
isFirstBlock = false
|
||||
if (!decodeOneBlock(cipherText, offset, len)) {
|
||||
throw RuntimeException("Unable to decode")
|
||||
}
|
||||
}
|
||||
if (mIndexPos == 8) {
|
||||
encodeOneBlock()
|
||||
}
|
||||
}
|
||||
|
||||
var outpos = 0
|
||||
while (plen != 0) {
|
||||
if (mIndexPos < 8) {
|
||||
mOutput[outpos++] = if (isFirstBlock)
|
||||
mIV[mIndexPos]
|
||||
else
|
||||
(cipherText[mPreOutPos + offset + mIndexPos] xor mIV[mIndexPos])
|
||||
while (len > 0) {
|
||||
if (mIndexPos < 8) {
|
||||
mInBlock[mIndexPos++] = plaintext[offset++]
|
||||
}
|
||||
if (mIndexPos == 8) {
|
||||
encodeOneBlock()
|
||||
}
|
||||
len--
|
||||
}
|
||||
g = 0
|
||||
while (g < 7) {
|
||||
if (mIndexPos < 8) {
|
||||
mInBlock[mIndexPos++] = 0.toByte()
|
||||
}
|
||||
if (mIndexPos == 8) {
|
||||
encodeOneBlock()
|
||||
}
|
||||
g++
|
||||
}
|
||||
return mOutput
|
||||
}
|
||||
|
||||
fun decrypt(cipherText: ByteArray, offset: Int, len: Int): ByteArray? {
|
||||
require(!(len % 8 != 0 || len < 16)) { "must len % 8 == 0 && len >= 16" }
|
||||
mIV = decode(cipherText, offset)
|
||||
mIndexPos = (mIV[0] and 7).toInt()
|
||||
var plen = len - mIndexPos - 10
|
||||
isFirstBlock = true
|
||||
if (plen < 0) {
|
||||
return null
|
||||
}
|
||||
mOutput = ByteArray(plen)
|
||||
mPreOutPos = 0
|
||||
mOutPos = 8
|
||||
++mIndexPos
|
||||
var g = 0
|
||||
while (g < 2) {
|
||||
if (mIndexPos < 8) {
|
||||
++mIndexPos
|
||||
++g
|
||||
}
|
||||
if (mIndexPos == 8) {
|
||||
isFirstBlock = false
|
||||
if (!decodeOneBlock(cipherText, offset, len)) {
|
||||
throw RuntimeException("Unable to decode")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var outpos = 0
|
||||
while (plen != 0) {
|
||||
if (mIndexPos < 8) {
|
||||
mOutput[outpos++] = if (isFirstBlock)
|
||||
mIV[mIndexPos]
|
||||
else
|
||||
(cipherText[mPreOutPos + offset + mIndexPos] xor mIV[mIndexPos])
|
||||
++mIndexPos
|
||||
}
|
||||
if (mIndexPos == 8) {
|
||||
mPreOutPos = mOutPos - 8
|
||||
isFirstBlock = false
|
||||
if (!decodeOneBlock(cipherText, offset, len)) {
|
||||
throw RuntimeException("Unable to decode")
|
||||
}
|
||||
}
|
||||
plen--
|
||||
}
|
||||
g = 0
|
||||
while (g < 7) {
|
||||
if (mIndexPos < 8) {
|
||||
if (cipherText[mPreOutPos + offset + mIndexPos].xor(mIV[mIndexPos]).toInt() != 0) {
|
||||
throw RuntimeException()
|
||||
} else {
|
||||
++mIndexPos
|
||||
}
|
||||
if (mIndexPos == 8) {
|
||||
mPreOutPos = mOutPos - 8
|
||||
isFirstBlock = false
|
||||
if (!decodeOneBlock(cipherText, offset, len)) {
|
||||
throw RuntimeException("Unable to decode")
|
||||
}
|
||||
}
|
||||
plen--
|
||||
}
|
||||
g = 0
|
||||
while (g < 7) {
|
||||
if (mIndexPos < 8) {
|
||||
if (cipherText[mPreOutPos + offset + mIndexPos].xor(mIV[mIndexPos]).toInt() != 0) {
|
||||
throw RuntimeException()
|
||||
} else {
|
||||
++mIndexPos
|
||||
}
|
||||
|
||||
if (mIndexPos == 8) {
|
||||
mPreOutPos = mOutPos
|
||||
if (!decodeOneBlock(cipherText, offset, len)) {
|
||||
throw RuntimeException("Unable to decode")
|
||||
}
|
||||
|
||||
if (mIndexPos == 8) {
|
||||
mPreOutPos = mOutPos
|
||||
if (!decodeOneBlock(cipherText, offset, len)) {
|
||||
throw RuntimeException("Unable to decode")
|
||||
}
|
||||
}
|
||||
g++
|
||||
}
|
||||
return mOutput
|
||||
g++
|
||||
}
|
||||
return mOutput
|
||||
}
|
||||
|
||||
return if (encrypt) {
|
||||
encrypt(data, 0, data.size)
|
||||
} else {
|
||||
try {
|
||||
return decrypt(data, 0, data.size)!!
|
||||
} catch (e: Exception) {
|
||||
println("Source: " + data.toUHexString(" "))
|
||||
println("Key: " + key.toUHexString(" "))
|
||||
throw e
|
||||
}
|
||||
return if (encrypt) {
|
||||
encrypt(data, 0, data.size)
|
||||
} else {
|
||||
try {
|
||||
return decrypt(data, 0, data.size)!!
|
||||
} catch (e: Exception) {
|
||||
println("Source: " + data.toUHexString(" "))
|
||||
println("Key: " + key.toUHexString(" "))
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
fun encrypt(source: ByteArray, key: ByteArray): ByteArray {
|
||||
return doOption(source, key, true)
|
||||
}
|
||||
|
||||
fun encrypt(source: ByteArray, keyHex: String): ByteArray {
|
||||
return encrypt(source, keyHex.hexToBytes())
|
||||
}
|
||||
|
||||
fun decrypt(source: ByteArray, key: ByteArray): ByteArray {
|
||||
return doOption(source, key, false)
|
||||
}
|
||||
|
||||
fun decrypt(source: ByteArray, keyHex: String): ByteArray {
|
||||
return decrypt(source, keyHex.hexToBytes())
|
||||
}
|
||||
|
||||
private fun pack(bytes: ByteArray, offset: Int, len: Int): Long {
|
||||
var result: Long = 0
|
||||
val max_offset = if (len > 8) offset + 8 else offset + len
|
||||
for (index in offset until max_offset) {
|
||||
result = result shl 8 or (bytes[index].toLong() and 0xffL)
|
||||
}
|
||||
return result shr 32 or (result and UINT32_MASK)
|
||||
}
|
||||
}
|
||||
|
||||
fun encrypt(source: ByteArray, key: ByteArray): ByteArray {
|
||||
return doOption(source, key, true)
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun encrypt(source: ByteArray, keyHex: String): ByteArray {
|
||||
return encrypt(source, keyHex.hexToBytes())
|
||||
}
|
||||
|
||||
fun decrypt(source: ByteArray, key: ByteArray): ByteArray {
|
||||
return doOption(source, key, false)
|
||||
}
|
||||
|
||||
fun decrypt(source: ByteArray, keyHex: String): ByteArray {
|
||||
return decrypt(source, keyHex.hexToBytes())
|
||||
}
|
||||
|
||||
@Suppress("SameParameterValue")
|
||||
private fun pack(bytes: ByteArray, offset: Int, len: Int): Long {
|
||||
var result: Long = 0
|
||||
val maxOffset = if (len > 8) offset + 8 else offset + len
|
||||
for (index in offset until maxOffset) {
|
||||
result = result shl 8 or (bytes[index].toLong() and 0xffL)
|
||||
}
|
||||
return result shr 32 or (result and UINT32_MASK)
|
||||
}
|
||||
}
|
@ -5,4 +5,4 @@ package net.mamoe.mirai.utils
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
internal annotation class TestedSuccessfully
|
||||
internal annotation class Tested
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
@ -26,14 +28,14 @@ fun ByteArray.toHexString(separator: String = " "): String = this.joinToString(s
|
||||
return@joinToString ret
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun ByteArray.toUHexString(separator: String = " "): String = this.toUByteArray().toUHexString(separator)
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@JvmSynthetic
|
||||
fun ByteArray.toUHexString(): String = this.toUByteArray().toUHexString()
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@JvmSynthetic
|
||||
fun UByteArray.toUHexString(separator: String = " "): String {
|
||||
return this.joinToString(separator) {
|
||||
@ -45,36 +47,36 @@ fun UByteArray.toUHexString(separator: String = " "): String {
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@JvmSynthetic
|
||||
fun UByteArray.toUHexString(): String = this.toUHexString(" ")
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun Byte.toUHexString(): String = this.toUByte().toString(16)
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun String.hexToBytes(): ByteArray = Protocol.hexToBytes(this)
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun String.hexToUBytes(): UByteArray = Protocol.hexToUBytes(this)
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun String.hexToInt(): Int = hexToBytes().toUInt().toInt()
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun ByteArray.toUInt(): UInt =
|
||||
this[0].toUInt().and(255u).shl(24) + this[1].toUInt().and(255u).shl(16) + this[2].toUInt().and(255u).shl(8) + this[3].toUInt().and(255u).shl(0)
|
||||
|
||||
open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream()) {
|
||||
open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray()
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
open fun toUByteArray(): UByteArray = (out as ByteArrayOutputStream).toByteArray().toUByteArray()
|
||||
}
|
||||
|
||||
@JvmSynthetic
|
||||
fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDataOutputStream().also(t).toByteArray()
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
fun getRandomByteArray(length: Int): ByteArray {
|
||||
val bytes = LinkedList<Byte>()
|
||||
repeat(length) { bytes.add((Math.random() * 255).toByte()) }
|
||||
|
@ -1,4 +1,5 @@
|
||||
@file:JvmName("Varint")
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
@ -21,7 +22,7 @@ fun encodeZigZag32(signedInt: Int): Long {
|
||||
return (signedInt shl 1 xor (signedInt shr 31)).toLong()
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@JvmSynthetic
|
||||
fun decodeZigZag32(uint: UInt): Int {
|
||||
return decodeZigZag32(uint.toLong())
|
||||
@ -39,25 +40,25 @@ fun decodeZigZag64(signedLong: Long): Long {
|
||||
return signedLong.ushr(1) xor -(signedLong and 1)
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataInputStream.readVarInt(): Int {
|
||||
return decodeZigZag32(this.readUnsignedVarInt())
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataInputStream.readUnsignedVarInt(): UInt {
|
||||
return read(this, 5).toUInt()
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataInputStream.readVarLong(): Long {
|
||||
return decodeZigZag64(readUnsignedVarLong().toLong())
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataInputStream.readUnsignedVarLong(): ULong {
|
||||
return read(this, 10).toULong()
|
||||
@ -68,7 +69,7 @@ fun DataOutputStream.writeVarInt(signedInt: Int) {
|
||||
this.writeUVarInt(encodeZigZag32(signedInt))
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeUVarInt(uint: UInt) {
|
||||
return writeUVarInt(uint.toLong())
|
||||
|
@ -1,47 +0,0 @@
|
||||
import net.mamoe.mirai.network.packet.login.ClientPasswordSubmissionPacket
|
||||
import net.mamoe.mirai.utils.toUHexString
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun main(){
|
||||
/*
|
||||
val data = "00 37 13 08 25 31 01 EB 10 08 30 69 50 1C 84 A9 C2 16 D7 52 B9 1C 79 CA 5A CF FD BC EB 10 08 30 69 50 1C 84 A9 C2 16 D7 52 B9 1C 79 CA 5A CF FD BC AE D8 A6 BB DC 21 6E 79 26 E1 A2 23 11 AA B0 9A AE D8 A6 BB DC 21 6E 79 26 E1 A2 23 11 AA B0 9A 76 E4 B8 DD 03 00 00 00 01 2E 01 00 00 68 52 00 00 00 00 A4 F1 91 88 C9 82 14 99 0C 9E 56 55 91 23 C8 3D C3 47 F0 25 A1 8E 74 EF 1E 0B 32 5B 20 8A FA 3B 0B 52 8F 86 E6 04 F1 D6 F8 63 75 60 8C 0C 7D 06 D1 E0 22 F8 49 EF AF 61 EE 7E 69 72 EB 10 08 30 69 50 1C 84 A9 C2 16 D7 52 B9 1C 79 CA 5A CF FD BC AE D8 A6 BB DC 21 6E 79 26 E1 A2 23 11 AA B0 9A 49 39 72 ED 61 12 B6 88 4D A2 56 23 E9 92 11 92 27 4A 70 00 C9 01 7B 03";
|
||||
val s = DataInputStream(data.hexToBytes().inputStream())
|
||||
val packet = ServerTouchResponsePacket(ServerTouchResponsePacket.Type.TYPE_08_25_31_01, s)
|
||||
packet.decode()
|
||||
System.out.println(packet.token.toUByteArray().toUHexString(" "))
|
||||
System.out.println(packet.loginTime.toUHexString(" "))
|
||||
System.out.println(packet.loginIP)
|
||||
*/
|
||||
|
||||
// val packet = ClientPasswordSubmissionPacket(1994701021,"xiaoqqq",)
|
||||
|
||||
/*
|
||||
val data = "00 01 09 00 70 00 01 5C 71 80 A6 BA 20 62 2E C1 BE BF F2 47 37 40 A1 00 38 91 25 85 58 18 D3 67 77 2C 4D 02 D8 66 A6 F7 3E 57 D8 CE 01 47 7F D0 8F 13 C8 3A E5 19 A2 60 BC 4C 9A 35 4E 92 9F 21 48 6C 67 68 36 6B 94 C1 6F 11 8D 55 6B 04 9A 22 C3 00 20 29 7E D4 A7 16 02 07 14 41 90 3A 65 06 AC CB 28 AB 90 DB 46 33 C9 C0 1D 06 44 7A 92 17 C3 A5 F3 00 00 01 03 00 14 00 01 00 10 60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6 01 07 01 D3 00 01 00 16 00 00 00 01 00 00 00 64 00 00 0D B6 00 09 3A 80 00 00 00 3C 00 02 2E 29 4E 47 5F 68 78 2C 47 25 5F 59 50 65 60 5D 00 88 00 04 5D 59 45 17 B7 5F F8 D4 00 00 00 00 00 78 38 E0 3B 23 4A C5 0E 93 CB C1 66 96 37 8B 46 B2 86 23 3F 2D 09 45 E0 16 1C E9 9C 11 7A FA 2D A8 50 47 42 74 01 06 84 76 0E 5F C6 04 29 1A 4A 65 AA 93 49 DF BD 00 ED 80 B8 26 CA 80 E8 20 6D 15 43 DD D8 E6 48 C2 8A 5A F8 70 6B 51 3A E2 2D 21 95 4B 6A 75 A8 90 CA B1 C0 E5 73 99 D7 59 D8 DD 3D C9 5C E4 49 61 22 11 60 85 48 C4 7D E0 84 62 AD B3 13 84 61 C1 9E 19 35 41 44 44 37 3F 21 33 64 4B 37 5D 77 6D 61 3F 00 78 00 01 5D 59 45 17 00 70 A4 D9 44 9E 95 51 B4 B0 91 CC 1E DB 34 F9 F7 13 8B 30 08 C0 AE 33 22 9C FF 87 CF 9B A2 B0 E5 E1 D0 E0 AD DD 8F E9 F6 1E 01 1F AA 74 46 66 B4 81 54 B9 29 E5 FC 0B 7F C9 13 AE 32 BA D6 55 2E B0 A1 30 24 B6 F2 E7 62 F9 2E 00 E4 51 61 50 7C D1 36 E8 61 96 36 FF B7 32 74 3C 2A F7 74 63 DA 7D 57 84 18 ED 84 E9 D8 87 6D 66 1D D5 84 D4 23 99 00 83 01 63 2A 69 2E 25 79 28 3B 29 33 29 40 28 54 7E 21 00 70 00 01 5D 59 45 17 00 68 6F 1F FB 31 7B D7 B7 D8 91 32 D7 20 8B 8A F6 02 C8 22 E5 24 8C 25 F2 6A C5 B0 ED 35 01 BF AF 42 72 33 4E FB 3F D3 02 BA F4 46 2B 68 20 0B E3 39 81 B1 D3 8A E0 1B 0F 69 D1 70 AE 49 A5 24 4F BB 58 4F F8 31 A0 37 4C CD F1 12 35 80 99 7D 25 CA F9 E9 45 B6 B0 57 56 66 61 C5 7B 90 57 BF E2 2C 94 91 80 1A B0 D7 21 A8 44 2C 33 4A 29 77 5F 71 40 41 38 3D 7A 41 65 33 01 08 00 29 00 01 00 25 00 1D 02 5B 14 28 E0 B9 91 E2 80 A2 CC 80 CF 89 E2 80 A2 CC 81 E0 B9 91 29 02 13 80 02 00 05 00 04 00 00 00 01 01 15 00 10 F9 86 85 81 30 F6 1B E0 E7 97 98 F6 46 C3 4F B2"
|
||||
val s = DataInputStream(data.hexToBytes().inputStream())
|
||||
val packet = ServerLoginResponseSuccessPacket(s,(data.length+1)/3)
|
||||
packet.decode()
|
||||
System.out.println("0828key: \n" + packet._0828_rec_decr_key.toUByteArray().toUHexString(" "))
|
||||
System.out.println("token88: \n" + packet.token88.toUByteArray().toUHexString(" "))
|
||||
System.out.println("token38: \n" + packet.token38.toUByteArray().toUHexString(" "))
|
||||
System.out.println("enckey: \n" + packet.encryptionKey.toUByteArray().toUHexString(" "))
|
||||
System.out.println("nick: " + packet.nick)
|
||||
System.out.println("age: " + packet.age)
|
||||
System.out.println("gender: " + packet.gender)
|
||||
*/
|
||||
|
||||
/*
|
||||
val data = "FB 01 04 03 33 00 01 00 BA 02 03 2C 13 00 05 01 00 00 01 23 00 38 F5 C3 CF F4 B4 27 C5 8F 9B D3 ED 18 73 7D E9 CB 43 1F 57 43 BE D3 1B 9A F5 26 2B F4 D9 43 14 9A ED 3B C3 6C E5 7F 4E B0 0C BA 55 57 18 06 78 E1 13 A7 B2 A8 7F 47 E1 1C 02 BC 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 00 82 00 00 00 35 08 03 00 00 00 BA 12 C3 02 00 00 00 04 67 41 4D 41 00 00 B1 8F 0B FC 61 05 00 00 00 01 73 52 47 42 00 AE CE 1C E9 00 00 00 6C 50 4C 54 45 F6 F8 F4 E3 EE FD E5 FD FF EE FD F0 F6 F9 E7 F7 F9 EC F4 FE FF F7 F7 F9 F5 F4 FF EC F7 FF E6 F4 E0 F5 FC F8 49 5B 8F CB DB FA BB C9 F5 2B 40 7C D6 E6 FF FD FB FF ED F1 F0 2A 43 B3 D6 F6 FF FC F1 FC 1C 38 91 A7 BD F6 63 74 BD 70 8B CC 34 4F A5 DE F3 F1 75 88 E7 A4 B7 D3 73 82 A1 8C A3 DC F3 FB D8 4D 68 B9 94 A8 FB 8D 9C B6 CB 42 B0 8E 00 00 0A 6F 49 44 41 54 58 C3 B4 57 89 76 EB 2A 12 14 20 B1 09 10 42 68 DF 2C FB FF FF 71 0A 79 49 E2 E4 CE CC 79 37 8F 13 59 B6 72 EC 2E AA BB AB 9A 2C FB 61 89 8F 95 E5 79 A9 70 CB B2 22 C7 2A 65 DB 5E 72 21 F1 A9 90 B2 28 C4 F9 AF 5F 5F 05 30 9C 28 D2 4B C6 58 F9 8C 92 17 39 13 6D 9B FF EB 10 8A 3B 0F 2F 10 52 64 45 51 64 42 A6 37 79 21 DA FC F2 6F 40 08 9F AE B7 9C A4 C8 27 31 F2 C4 50 A4 D4 9C F9 01 BC A2 90 0F 08 E1 2F AE 1F E3 7E 7D 24 52 F4 67 2C 91 02 E3 CA 13 2F 78 97 00 86 DF 4E C4 23 56 F1 F8 7B 10 90 42 3D D2 93 EE 27 04 F1 80 F0 4B 99 10 4F 62 5E D9 2D EE 57 8A F1 A0 E1 64 20 2B 55 F9 C8 C3 67 08 F8 81 7F F2 F7 BE FD 67 1D 9E 9B 4F EB 89 25 21 28 19 63 09 5D A9 94 2A 59 AA 87 B3 32 4E 84 FF 3C 13 8F AF 06 F1 29 FD E2 C1 02 54 E0 8C 5E 5C 2E A5 72 43 65 F4 E5 72 61 5C 4A 45 81 41 97 79 0A 9E FF 62 22 C2 EB 7E 42 48 45 80 2B 0F 58 B9 66 D6 1C 63 75 D3 97 BC F4 08 0F 08 5C 6B 8D CC 14 1F 10 C4 5F B4 C3 37 66 EE E5 78 CF 42 12 05 CD F5 4D 29 EB 36 AD 19 82 CF 76 35 C6 86 B2 94 A7 36 FC 62 39 BE A8 B8 D7 02 78 08 8F 66 E4 44 45 DF BB AB A3 34 92 14 DF 54 C6 32 1D 00 21 7F 41 08 7F C9 7F F8 28 88 4F B5 90 89 3A 21 90 9E DF E8 DE 34 4D 8C D1 EF C6 AC 6B 7F 74 8E B1 FA 84 90 7F B0 F0 CF 5A E2 27 4C AF 8E 28 EF 24 48 B2 AF B1 9A 96 3E F6 43 75 38 6F 29 5D 1A C7 59 78 87 F0 1B B2 F0 95 05 3C 93 B2 26 B6 9F BA 18 AB AE 59 EC 88 17 17 A9 8F 4B B3 CE 60 A1 CD F2 CB 03 42 10 7F D9 06 1F 76 80 8E 4F 6D 9F 56 99 05 25 A5 DD AA EB 62 7A 6F 87 E6 B8 0E 5D 33 C6 99 C6 C4 02 24 EB 74 8C 87 98 64 F8 5E A9 9E 1E F7 72 FB FF B3 21 8A A4 00 01 00 28 F9 59 C5 E6 34 43 53 95 C8 17 2E 62 78 BF E8 27 BF 20 BA 11 5A 74 D1 7C D0 95 6C F6 A3 41 D2 84 BD 7D F6 64 BC 27 40 50 01 15 00 10 44 98 EB B8 30 3B DE 7D 2B CC 4C 41 B3 1C 92 86"
|
||||
val s = DataInputStream(data.hexToBytes().inputStream())
|
||||
val packet = ServerLoginResponseVerificationCodePacket(s,(data.length+1)/3)
|
||||
packet.decode()
|
||||
println(packet.token00BA.toUByteArray().toUHexString(" "))
|
||||
println(packet.verifyCode.toUByteArray().toUHexString(" "))
|
||||
println(packet.verifyCodeLength)
|
||||
|
||||
File(System.getProperty("user.dir") + "/5.png").createNewFile()
|
||||
packet.verifyCode.inputStream().transferTo(FileOutputStream(System.getProperty("user.dir") + "/5.png"))
|
||||
*/
|
||||
|
||||
val packet = ClientPasswordSubmissionPacket(1994701021, "xiaoqqq", 131513, "123.123.123.123", "tgtgtKey".toByteArray(), "".toByteArray())
|
||||
packet.encodeToByteArray().toUByteArray().toUHexString(" ")
|
||||
}
|
Loading…
Reference in New Issue
Block a user