Message receiver is working!

This commit is contained in:
Him188moe 2019-08-31 23:46:46 +08:00
parent c5b01fbf5f
commit c7b0b58c34
33 changed files with 384 additions and 586 deletions

View File

@ -5,7 +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.client.touch.ClientTouchPacket;
import net.mamoe.mirai.network.packet.ClientTouchPacket;
import net.mamoe.mirai.task.MiraiTaskManager;
import net.mamoe.mirai.utils.LoggerTextFormat;
import net.mamoe.mirai.utils.MiraiLogger;

View File

@ -1,20 +1,10 @@
package net.mamoe.mirai.network
import net.mamoe.mirai.MiraiServer
import net.mamoe.mirai.network.packet.client.ClientPacket
import net.mamoe.mirai.network.packet.client.login.*
import net.mamoe.mirai.network.packet.client.session.*
import net.mamoe.mirai.network.packet.client.touch.ClientHeartbeatPacket
import net.mamoe.mirai.network.packet.client.touch.ClientRefreshSKeyRequestPacket
import net.mamoe.mirai.network.packet.client.touch.ServerHeartbeatResponsePacket
import net.mamoe.mirai.network.packet.client.writeHex
import net.mamoe.mirai.network.packet.client.writeRandom
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.event.*
import net.mamoe.mirai.network.packet.server.login.*
import net.mamoe.mirai.network.packet.server.security.*
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacket
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacketEncrypted
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.network.packet.login.*
import net.mamoe.mirai.network.packet.verification.ServerVerificationCodePacket
import net.mamoe.mirai.network.packet.verification.ServerVerificationCodePacketEncrypted
import net.mamoe.mirai.task.MiraiThreadPool
import net.mamoe.mirai.util.*
import net.mamoe.mirai.utils.MiraiLogger
@ -216,7 +206,7 @@ class RobotNetworkHandler(val number: Int, private val password: String) {
this.cookies = "uin=o" + this.number + ";skey=" + this.sKey + ";"
MiraiThreadPool.getInstance().scheduleWithFixedDelay({
sendPacket(ClientRefreshSKeyRequestPacket(this.number, this.sessionKey))
sendPacket(ClientSKeyRefreshmentRequestPacket(this.number, this.sessionKey))
}, 1800000, 1800000, TimeUnit.MILLISECONDS)
this.gtk = getGTK(sKey)

View File

@ -1,11 +1,6 @@
package net.mamoe.mirai.network.packet.client.session
package net.mamoe.mirai.network.packet
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.*
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.dataInputStream
import net.mamoe.mirai.network.packet.server.goto
import net.mamoe.mirai.util.TEACryptor
import java.io.DataInputStream

View File

@ -1,9 +1,7 @@
package net.mamoe.mirai.network.packet.client
package net.mamoe.mirai.network.packet
import lombok.Getter
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.Packet
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.util.*
import java.io.DataOutputStream
import java.io.IOException

View File

@ -1,9 +1,6 @@
package net.mamoe.mirai.network.packet.client.touch
package net.mamoe.mirai.network.packet
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.*
import net.mamoe.mirai.network.packet.server.ServerPacket
import java.io.DataInputStream
import java.io.IOException

View File

@ -1,14 +1,6 @@
package net.mamoe.mirai.network.packet.server.event
package net.mamoe.mirai.network.packet
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.ClientPacket
import net.mamoe.mirai.network.packet.client.encryptAndWrite
import net.mamoe.mirai.network.packet.client.writeHex
import net.mamoe.mirai.network.packet.client.writeQQ
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.dataInputStream
import net.mamoe.mirai.network.packet.server.goto
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.toUHexString
import java.io.DataInputStream

View File

@ -1,23 +0,0 @@
package net.mamoe.mirai.network.packet;
/**
* @author Him188moe
*/
public final class PacketUtil {
/**
* 易语言返回的 string(valueof
*/
public static int getGTK(String sKey) {
int init = 5381;
int i = 0;
int length = sKey.length();
while (i++ < length) {
init += init << 5 + sKey.charAt(i);
}
return init & 2147483647;
}
}

View File

@ -0,0 +1,70 @@
package net.mamoe.mirai.network.packet
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.util.TEACryptor
import java.io.DataInputStream
/**
* @author Him188moe
*/
@ExperimentalUnsignedTypes
@PacketId("00 1D")
class ClientSKeyRequestPacket(
private val qq: Int,
private val sessionKey: ByteArray
) : ClientPacket() {
override fun encode() {
this.writeRandom(2)//part of packet id
this.writeQQ(qq)
this.writeHex(Protocol._fixVer)
this.encryptAndWrite(sessionKey) {
it.writeHex("33 00 05 00 08 74 2E 71 71 2E 63 6F 6D 00 0A 71 75 6E 2E 71 71 2E 63 6F 6D 00 0C 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 00 0C 6A 75 62 61 6F 2E 71 71 2E 63 6F 6D 00 09 6B 65 2E 71 71 2E 63 6F 6D")
}
}
}
/**
* @author Him188moe
*/
@PacketId("00 1D")
@ExperimentalUnsignedTypes
class ClientSKeyRefreshmentRequestPacket(
private val qq: Int,
private val sessionKey: ByteArray
) : ClientPacket() {
override fun encode() {
this.writeRandom(2)//part of packet id
this.writeQQ(qq)
this.encryptAndWrite(sessionKey) {
it.writeHex("33 00 05 00 08 74 2E 71 71 2E 63 6F 6D 00 0A 71 75 6E 2E 71 71 2E 63 6F 6D 00 0C 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 00 0C 6A 75 62 61 6F 2E 71 71 2E 63 6F 6D 00 09 6B 65 2E 71 71 2E 63 6F 6D")
}
}
}
/**
* @author Him188moe
*/
class ServerSKeyResponsePacket(input: DataInputStream) : ServerPacket(input) {
lateinit var sKey: String
override fun decode() {
this.sKey = String(this.input.goto(4).readNBytes(10))
}
}
/**
* @author Him188moe
*/
class ServerSKeyResponsePacketEncrypted(inputStream: DataInputStream) : ServerPacket(inputStream) {
override fun decode() {
}
fun decrypt(sessionKey: ByteArray): ServerSKeyResponsePacket {
this.input goto 14
val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }
return ServerSKeyResponsePacket(TEACryptor.decrypt(data, sessionKey).dataInputStream());
}
}

View File

@ -1,7 +1,5 @@
package net.mamoe.mirai.network.packet.server.event
package net.mamoe.mirai.network.packet
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.goto
import net.mamoe.mirai.utils.MiraiLogger
import java.io.ByteArrayOutputStream
import java.io.DataInputStream

View File

@ -1,16 +1,7 @@
package net.mamoe.mirai.network.packet.server
package net.mamoe.mirai.network.packet
import net.mamoe.mirai.network.packet.Packet
import net.mamoe.mirai.network.packet.client.session.ServerAccountInfoResponsePacketEncrypted
import net.mamoe.mirai.network.packet.client.toHexString
import net.mamoe.mirai.network.packet.client.touch.ServerHeartbeatResponsePacket
import net.mamoe.mirai.network.packet.server.event.ServerMessageEventPacketRawEncoded
import net.mamoe.mirai.network.packet.server.login.*
import net.mamoe.mirai.network.packet.server.security.ServerLoginSuccessPacket
import net.mamoe.mirai.network.packet.server.security.ServerSKeyResponsePacketEncrypted
import net.mamoe.mirai.network.packet.server.security.ServerSessionKeyResponsePacketEncrypted
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacket
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacketEncrypted
import net.mamoe.mirai.network.packet.login.*
import net.mamoe.mirai.network.packet.verification.ServerVerificationCodePacketEncrypted
import net.mamoe.mirai.util.getAllDeclaredFields
import net.mamoe.mirai.util.hexToBytes
import net.mamoe.mirai.util.toUHexString
@ -73,9 +64,6 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
"08 28 04 34" -> ServerSessionKeyResponsePacketEncrypted(stream)
"00 81 EC 78" -> UnknownPacket(stream)
"00 81 AD 7A" -> UnknownPacket(stream)
else -> when (idHex.substring(0, 5)) {
"00 EC" -> ServerLoginSuccessPacket(stream)
"00 1D" -> ServerSKeyResponsePacketEncrypted(stream)
@ -88,6 +76,8 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
"00 CE", "00 17" -> ServerMessageEventPacketRawEncoded(stream, idHex.hexToBytes())
"00 81" -> UnknownServerPacket(stream)
else -> throw IllegalArgumentException(idHex)
}
}

View File

@ -0,0 +1,121 @@
package net.mamoe.mirai.network.packet
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.util.ByteArrayDataOutputStream
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.getRandomKey
import net.mamoe.mirai.util.lazyEncode
import java.io.DataInputStream
import java.net.InetAddress
/**
* @author Him188moe
*/
@ExperimentalUnsignedTypes
@PacketId("08 28 04 34")
class ClientSessionRequestPacket(
private val qq: Int,
private val serverIp: String,
private val loginIP: String,
private val md5_32: ByteArray,
private val token38: ByteArray,
private val token88: ByteArray,
private val encryptionKey: ByteArray,
private val tlv0105: ByteArray
) : ClientPacket() {
override fun encode() {
this.writeQQ(qq)
this.writeHex("02 00 00 00 01 2E 01 00 00 68 52 00 30 00 3A")
this.writeHex("00 38")
this.write(token38)
this.write(TEACryptor.encrypt(object : ByteArrayDataOutputStream() {
override fun toByteArray(): ByteArray {
this.writeHex("00 07 00 88")
this.write(token88)
this.writeHex("00 0C 00 16 00 02 00 00 00 00 00 00 00 00 00 00")
this.writeIP(serverIp)
this.writeHex("1F 40 00 00 00 00 00 15 00 30 00 01")//fix1
this.writeHex("01 92 A5 D2 59 00 10 54 2D CF 9B 60 BF BB EC 0D D4 81 CE 36 87 DE 35 02 AE 6D ED DC 00 10 ")
this.writeHex(Protocol._0836fix)
this.writeHex("00 36 00 12 00 02 00 01 00 00 00 05 00 00 00 00 00 00 00 00 00 00")
this.writeHex(Protocol._0825data0)
this.writeHex(Protocol._0825data2)
this.writeQQ(qq)
this.writeHex("00 00 00 00 00 1F 00 22 00 01")
this.writeHex("1A 68 73 66 E4 BA 79 92 CC C2 D4 EC 14 7C 8B AF 43 B0 62 FB 65 58 A9 EB 37 55 1D 26 13 A8 E5 3D")//device ID
this.write(tlv0105)
this.writeHex("01 0B 00 85 00 02")
this.writeHex("B9 ED EF D7 CD E5 47 96 7A B5 28 34 CA 93 6B 5C")//fix2
this.write(getRandomKey(1))
this.writeHex("10 00 00 00 00 00 00 00 02")
//fix3
this.writeHex("00 63 3E 00 63 02 04 03 06 02 00 04 00 52 D9 00 00 00 00 A9 58 3E 6D 6D 49 AA F6 A6 D9 33 0A E7 7E 36 84 03 01 00 00 68 20 15 8B 00 00 01 02 00 00 03 00 07 DF 00 0A 00 0C 00 01 00 04 00 03 00 04 20 5C 00")
this.write(md5_32)
this.writeHex("68")
this.writeHex("00 00 00 00 00 2D 00 06 00 01")
this.writeIP(InetAddress.getLocalHost().hostAddress)
return super.toByteArray()
}
}.toByteArray(), encryptionKey))
}
}
/**
* Dispose_0828
*
* @author Him188moe
*/
class ServerSessionKeyResponsePacket(inputStream: DataInputStream, val dataLength: Int) : ServerPacket(inputStream) {
lateinit var sessionKey: ByteArray
lateinit var tlv0105: ByteArray
@ExperimentalUnsignedTypes
override fun decode() {
when (dataLength) {
407 -> {
input goto 25
sessionKey = input.readNBytes(16)
}
439 -> {
input.goto(63)
sessionKey = input.readNBytes(16)
}
512,
527 -> {
input.goto(63)
sessionKey = input.readNBytes(16)
tlv0105 = lazyEncode {
it.writeHex("01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00")
input.goto(dataLength - 122)
it.write(input.readNBytes(56))
it.writeHex("00 40 02 02 03 3C 01 03 00 00")
input.goto(dataLength - 55)
it.write(input.readNBytes(56))
} //todo 这个 tlv0105似乎可以保存起来然后下次登录时使用.
}
else -> throw IllegalArgumentException(dataLength.toString())
}
//tlv0105 = "01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00" + 取文本中间(data, 取文本长度(data) 367, 167) “00 40 02 02 03 3C 01 03 00 00 ” 取文本中间 (data, 取文本长度 (data) 166, 167)
}
}
class ServerSessionKeyResponsePacketEncrypted(inputStream: DataInputStream) : ServerPacket(inputStream) {
override fun decode() {
}
fun decrypt(_0828_rec_decr_key: ByteArray): ServerSessionKeyResponsePacket {
this.input goto 14
val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }
return ServerSessionKeyResponsePacket(TEACryptor.decrypt(data, _0828_rec_decr_key).dataInputStream(), data.size);
}
}

View File

@ -0,0 +1,133 @@
package net.mamoe.mirai.network.packet
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.util.*
import java.io.DataInputStream
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
*
* @author Him188moe
*/
class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) {
var serverIP: String? = null;
var loginTime: Int = 0
lateinit var loginIP: String
lateinit var token0825: ByteArray
lateinit var tgtgtKey: ByteArray
enum class Type {
TYPE_08_25_31_01,
TYPE_08_25_31_02,
}
@ExperimentalUnsignedTypes
override fun decode() {
when (val id = input.readByte().toUByte().toInt()) {
0xFE -> {
input.skip(94)
serverIP = input.readIP()
}
0x00 -> {
input.skip(4)
token0825 = input.readNBytes(56)
input.skip(6)
loginTime = input.readInt()
loginIP = input.readIP()
tgtgtKey = getRandomKey(16)
}
else -> {
throw IllegalStateException(arrayOf(id.toUByte()).toUByteArray().toUHexString())
}
}
}
}
class ServerTouchResponsePacketEncrypted(private val type: ServerTouchResponsePacket.Type, inputStream: DataInputStream) : ServerPacket(inputStream) {
override fun decode() {
}
@ExperimentalUnsignedTypes
fun decrypt(): ServerTouchResponsePacket {
input.skip(7)
var bytes = input.readAllBytes();
bytes = bytes.copyOfRange(0, bytes.size - 1);
println(bytes.toUByteArray().toUHexString())
return ServerTouchResponsePacket(DataInputStream(TEACryptor.decrypt(bytes, when (type) {
ServerTouchResponsePacket.Type.TYPE_08_25_31_02 -> Protocol.redirectionKey.hexToBytes()
ServerTouchResponsePacket.Type.TYPE_08_25_31_01 -> Protocol._0825key.hexToBytes()
}).inputStream()));
}
}
/**
* The packet to touch server, that is, to start the connection to the server.
*
* @author Him188moe
*/
@ExperimentalUnsignedTypes
@PacketId("08 25 31 01")
class ClientTouchPacket(val qq: Int, val serverIp: String) : ClientPacket() {
@ExperimentalUnsignedTypes
@Throws(IOException::class)
override fun encode() {
this.writeQQ(qq)
this.writeHex(Protocol.fixVer)
this.writeHex(Protocol._0825key)
this.write(TEACryptor.CRYPTOR_0825KEY.encrypt(object : ByteArrayDataOutputStream() {
@Throws(IOException::class)
override fun toByteArray(): ByteArray {
this.writeHex(Protocol._0825data0)
this.writeHex(Protocol._0825data2)
this.writeQQ(qq)
this.writeHex("00 00 00 00 03 09 00 08 00 01")
this.writeIP(serverIp);
this.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")
this.writeHex(Protocol.publicKey)
println(super.toUByteArray().toUHexString())
return super.toByteArray()
}
}.toByteArray()))
}
}
/**
* Server redirection (0825 response)
*
* @author Him188moe
*/
@ExperimentalUnsignedTypes
@PacketId("08 25 31 02")
class ClientServerRedirectionPacket(private val serverIP: String, private val qq: Int) : ClientPacket() {
@ExperimentalUnsignedTypes
override fun encode() {
this.writeQQ(qq)
this.writeHex(Protocol.fixVer)
this.writeHex(Protocol.redirectionKey)
this.write(TEACryptor.encrypt(object : ByteArrayDataOutputStream() {
@Throws(IOException::class)
override fun toByteArray(): ByteArray {
this.writeHex(Protocol._0825data0)
this.writeHex(Protocol._0825data2)
this.writeQQ(qq)
this.writeHex("00 01 00 00 03 09 00 0C 00 01")
this.writeIP(serverIP)
this.writeHex("01 6F A1 58 22 01 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 03 00 19")
this.writeHex(Protocol.publicKey)
return super.toByteArray()
}
}.toByteArray(), Protocol.redirectionKey.hexToBytes()))
}
}

View File

@ -0,0 +1,12 @@
package net.mamoe.mirai.network.packet
import java.io.DataInputStream
/**
* @author Him188moe
*/
class UnknownServerPacket(input: DataInputStream) : ServerPacket(input) {
override fun decode() {
}
}

View File

@ -1,11 +0,0 @@
package net.mamoe.mirai.network.packet.client
/**
* @author Him188moe
*/
@ExperimentalUnsignedTypes
class ClientSendMessagePacket : ClientPacket() {
override fun encode() {
}
}

View File

@ -1,43 +0,0 @@
package net.mamoe.mirai.network.packet.client.login
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.ClientPacket
import net.mamoe.mirai.network.packet.client.writeHex
import net.mamoe.mirai.network.packet.client.writeIP
import net.mamoe.mirai.network.packet.client.writeQQ
import net.mamoe.mirai.util.ByteArrayDataOutputStream
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.hexToBytes
import java.io.IOException
/**
* Server redirection (0825 response)
*
* @author Him188moe
*/
@ExperimentalUnsignedTypes
@PacketId("08 25 31 02")
class ClientServerRedirectionPacket(private val serverIP: String, private val qq: Int) : ClientPacket() {
@ExperimentalUnsignedTypes
override fun encode() {
this.writeQQ(qq)
this.writeHex(Protocol.fixVer)
this.writeHex(Protocol.redirectionKey)
this.write(TEACryptor.encrypt(object : ByteArrayDataOutputStream() {
@Throws(IOException::class)
override fun toByteArray(): ByteArray {
this.writeHex(Protocol._0825data0)
this.writeHex(Protocol._0825data2)
this.writeQQ(qq)
this.writeHex("00 01 00 00 03 09 00 0C 00 01")
this.writeIP(serverIP)
this.writeHex("01 6F A1 58 22 01 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 03 00 19")
this.writeHex(Protocol.publicKey)
return super.toByteArray()
}
}.toByteArray(), Protocol.redirectionKey.hexToBytes()))
}
}

View File

@ -1,25 +0,0 @@
package net.mamoe.mirai.network.packet.client.session
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.*
/**
* @author Him188moe
*/
@ExperimentalUnsignedTypes
@PacketId("00 1D")
class ClientSKeyRequestPacket(
private val qq: Int,
private val sessionKey: ByteArray
) : ClientPacket() {
override fun encode() {
this.writeRandom(2)//part of packet id
this.writeQQ(qq)
this.writeHex(Protocol._fixVer)
this.encryptAndWrite(sessionKey) {
it.writeHex("33 00 05 00 08 74 2E 71 71 2E 63 6F 6D 00 0A 71 75 6E 2E 71 71 2E 63 6F 6D 00 0C 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 00 0C 6A 75 62 61 6F 2E 71 71 2E 63 6F 6D 00 09 6B 65 2E 71 71 2E 63 6F 6D")
}
}
}

View File

@ -1,102 +0,0 @@
package net.mamoe.mirai.network.packet.client.touch
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.ClientPacket
import net.mamoe.mirai.network.packet.client.writeHex
import net.mamoe.mirai.network.packet.client.writeIP
import net.mamoe.mirai.network.packet.client.writeQQ
import net.mamoe.mirai.util.ByteArrayDataOutputStream
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.toUHexString
import java.io.IOException
/**
* The packet to touch server, that is, to start the connection to the server.
*
* @author Him188moe
*/
@ExperimentalUnsignedTypes
@PacketId("08 25 31 01")
class ClientTouchPacket(val qq: Int, val serverIp: String) : ClientPacket() {
//已经完成测试
@ExperimentalUnsignedTypes
@Throws(IOException::class)
override fun encode() {
//println(this.toUByteArray().toUHexString(" "))
//exitProcess(1)
this.writeQQ(qq)
this.writeHex(Protocol.fixVer)
this.writeHex(Protocol._0825key)
this.write(TEACryptor.CRYPTOR_0825KEY.encrypt(object : ByteArrayDataOutputStream() {
@Throws(IOException::class)
override fun toByteArray(): ByteArray {
this.writeHex(Protocol._0825data0)
this.writeHex(Protocol._0825data2)
this.writeQQ(qq)
this.writeHex("00 00 00 00 03 09 00 08 00 01")
//this.writeIP("192.168.1.1");
this.writeIP(serverIp);
//this.writeIP("123456789")
this.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")
this.writeHex(Protocol.publicKey)
println(super.toUByteArray().toUHexString())
return super.toByteArray()
}
}.toByteArray()))
}
}
@ExperimentalUnsignedTypes
fun main() {
val pk = ClientTouchPacket(1994701021, "123.123.123.123")
pk.encode()
pk.writeHex(Protocol.tail)
//println("pk.toByteArray() = " + pk.toUByteArray().contentToString())
println(pk.toUByteArray().toUHexString(" "))
/*
println(object : ByteArrayDataOutputStream() {
@Throws(IOException::class)
override fun toUByteArray(): UByteArray {
this.writeInt(1994701021)
return super.toUByteArray()
}
}.toUByteArray().toUHexString())*/
/*
println(object : ByteArrayDataOutputStream() {
@Throws(IOException::class)
override fun toUByteArray(): UByteArray {
//this.writeIP("192.168.1.1")
this.writeHex(Protocol._0825data0)
this.writeHex(Protocol._0825data2)
this.writeQQ(1994701021)
this.writeHex("00 00 00 00 03 09 00 08 00 01")
//this.writeIP(Protocol.SERVER_IP.get(2));
this.writeIP("192.168.1.1")
this.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")
this.writeHex(Protocol.publicKey)
return super.toUByteArray()
}
}.toUByteArray().toUHexString(" "))
*/
}
//
//mirai: 00 18 00 16 00 01 00 00 04 53 00 00 00 01 00 00 15 85 76 E4 B8 DD 00 00 00 00 03 09 00 08 00 01 C0 A8 01 01 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 02 6D 28 41 D2 A5 6F D2 FC 3E 2A 1F 03 75 DE 6E 28 8F A8 19 3E 5F 16 49 D3
//epl : 00 18 00 16 00 01 00 00 04 53 00 00 00 01 00 00 15 85 76 E4 B8 DD 00 00 00 00 03 09 00 08 00 01 C0 A8 01 01 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 02 6D 28 41 D2 A5 6F D2 FC 3E 2A 1F 03 75 DE 6E 28 8F A8 19 3E 5F 16 49 D3
//encryption data
//mirai: 00 18 00 16 00 01 00 00 04 53 00 00 00 01 00 00 15 85 76 E4 B8 DD 00 00 00 00 03 09 00 08 00 01 C0 A8 01 01 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 02 6D 28 41 D2 A5 6F D2 FC 3E 2A 1F 03 75 DE 6E 28 8F A8 19 3E 5F 16 49 D3
//epl : 00 18 00 16 00 01 00 00 04 53 00 00 00 01 00 00 15 85 76 E4 B8 DD 00 00 00 00 03 09 00 08 00 01 C0 A8 01 01 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 02 6D 28 41 D2 A5 6F D2 FC 3E 2A 1F 03 75 DE 6E 28 8F A8 19 3E 5F 16 49 D3
//mirai: 02 37 13 08 25 31 01 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
//epl : 02 37 13 08 25 31 01 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 F0 1B 0A 8D 98 99 A9 78 B3 82 69 91 B1 8C FD 64 AC C1 DF B5 A1 A6 4C AC B6 CC A3 B2 11 51 15 00 A4 01 75 7C 61 83 C1 89 3E 93 42 A1 AF D4 1B B3 81 4E 52 67 C1 15 42 5D 28 00 3D 1E 40 28 B1 C9 CE 08 15 F3 2B B5 5A 88 59 4E F4 9A 15 CB 77 BE 56 86 16 CD 4F CD F6 14 D2 A6 B0 7B F1 22 B9 DD 64 98 5C 93 AE 6F 6C 43 03

View File

@ -1,22 +0,0 @@
package net.mamoe.mirai.network.packet.client.touch
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.*
/**
* @author Him188moe
*/
@PacketId("00 1D")
@ExperimentalUnsignedTypes
class ClientRefreshSKeyRequestPacket(
private val qq: Int,
private val sessionKey: ByteArray
) : ClientPacket() {
override fun encode() {
this.writeRandom(2)//part of packet id
this.writeQQ(qq)
this.encryptAndWrite(sessionKey) {
it.writeHex("33 00 05 00 08 74 2E 71 71 2E 63 6F 6D 00 0A 71 75 6E 2E 71 71 2E 63 6F 6D 00 0C 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 00 0C 6A 75 62 61 6F 2E 71 71 2E 63 6F 6D 00 09 6B 65 2E 71 71 2E 63 6F 6D")
}
}
}

View File

@ -1,12 +1,9 @@
package net.mamoe.mirai.network.packet.client.login
package net.mamoe.mirai.network.packet.login
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.*
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.util.*
import java.io.DataOutputStream
import java.net.InetAddress
import kotlin.system.exitProcess
/**
* Password submission (0836_622)
@ -40,38 +37,8 @@ class ClientPasswordSubmissionPacket(
}
}
@UseExperimental(ExperimentalUnsignedTypes::class)
fun main() {
println(InetAddress.getLocalHost().hostName)
exitProcess(0)
val loginTime = "5D 60 F6 33".hexToInt()
println(loginTime)
val loginIP = "AB 70 E2 96".let { it.split(" ").map { it.hexToByte() }.joinToString(".") { it.toString() } }
val tgtgtKey = "68 25 55 61 52 66 4A 54 71 6A 71 5A 24 50 27 6D".hexToBytes()
val token0825 = "56 3A E4 8B B4 64 D2 72 60 FE 01 54 FC B1 5F 88 E0 BA 64 1A 55 F2 84 FC 97 D0 BF 5F 47 A8 D9 76 BB FB 4A 7A F3 5E 0E A4 8E CA 8F 27 C2 02 6E 5D E7 68 9F 7C CF 91 83 F4".hexToBytes()
val token00ba = "57 3A 37 C3 FB A0 C3 E5 AE F3 0E B6 03 DE BF 9E E2 B5 C5 FE A0 F0 03 4F F7 8A 5C 29 5C E0 5A A2 89 D5 3F 60 E2 B2 81 FE D4 16 04 D4 E3 C6 4A D7 A9 D9 E6 FC 2E 7E 0C F3".hexToBytes()
val tlv_0006_encr = "0D DF 92 9C 5A 08 D1 67 FD 7D D6 DE CE D0 92 39 79 17 53 57 41 9B D6 D3 F9 F8 9A 3B E1 C2 3A E7 CF 02 6E 5E 36 B7 6D CF 33 66 77 FE AC 58 93 A3 85 E7 AF 6F 2D A2 74 E2 60 28 4B 29 17 04 79 95 39 D4 BF 4D C1 ED 61 49 13 23 9D 71 62 29 AF 87 D7 E3 42 49 88 3F D8 5C DB 9F 9E 5A 2A EA 02 F6 4F 2B D3 5B AF BE 0C B2 54 46 AE 99 1B 07 0B BE 6A C2 29 18 25 6A 95 0A".hexToBytes()
ClientLoginResendPacket3104(
1994701021,
"xiaoqqq",
loginTime,
loginIP,
tgtgtKey,
token0825,
token00ba,
tlv_0006_encr
).let { it.encode();println(it.toUByteArray().toUHexString()) }
}
@PacketId("08 36 31 04")
@ExperimentalUnsignedTypes//todo 测试出来这个包长度有问题
@ExperimentalUnsignedTypes
class ClientLoginResendPacket3104(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray, tlv_0006_encr: ByteArray? = null)
: ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA, tlv_0006_encr)
@ -116,58 +83,6 @@ open class ClientLoginResendPacket internal constructor(
}
@ExperimentalUnsignedTypes
@PacketId("08 28 04 34")
class ClientSessionRequestPacket(
private val qq: Int,
private val serverIp: String,
private val loginIP: String,
private val md5_32: ByteArray,
private val token38: ByteArray,
private val token88: ByteArray,
private val encryptionKey: ByteArray,
private val tlv0105: ByteArray
) : ClientPacket() {
override fun encode() {
this.writeQQ(qq)
this.writeHex("02 00 00 00 01 2E 01 00 00 68 52 00 30 00 3A")
this.writeHex("00 38")
this.write(token38)
this.write(TEACryptor.encrypt(object : ByteArrayDataOutputStream() {
override fun toByteArray(): ByteArray {
this.writeHex("00 07 00 88")
this.write(token88)
this.writeHex("00 0C 00 16 00 02 00 00 00 00 00 00 00 00 00 00")
this.writeIP(serverIp)
this.writeHex("1F 40 00 00 00 00 00 15 00 30 00 01")//fix1
this.writeHex("01 92 A5 D2 59 00 10 54 2D CF 9B 60 BF BB EC 0D D4 81 CE 36 87 DE 35 02 AE 6D ED DC 00 10 ")
this.writeHex(Protocol._0836fix)
this.writeHex("00 36 00 12 00 02 00 01 00 00 00 05 00 00 00 00 00 00 00 00 00 00")
this.writeHex(Protocol._0825data0)
this.writeHex(Protocol._0825data2)
this.writeQQ(qq)
this.writeHex("00 00 00 00 00 1F 00 22 00 01")
this.writeHex("1A 68 73 66 E4 BA 79 92 CC C2 D4 EC 14 7C 8B AF 43 B0 62 FB 65 58 A9 EB 37 55 1D 26 13 A8 E5 3D")//device ID
this.write(tlv0105)
this.writeHex("01 0B 00 85 00 02")
this.writeHex("B9 ED EF D7 CD E5 47 96 7A B5 28 34 CA 93 6B 5C")//fix2
this.write(getRandomKey(1))
this.writeHex("10 00 00 00 00 00 00 00 02")
//fix3
this.writeHex("00 63 3E 00 63 02 04 03 06 02 00 04 00 52 D9 00 00 00 00 A9 58 3E 6D 6D 49 AA F6 A6 D9 33 0A E7 7E 36 84 03 01 00 00 68 20 15 8B 00 00 01 02 00 00 03 00 07 DF 00 0A 00 0C 00 01 00 04 00 03 00 04 20 5C 00")
this.write(md5_32)
this.writeHex("68")
this.writeHex("00 00 00 00 00 2D 00 06 00 01")
this.writeIP(InetAddress.getLocalHost().hostAddress)
return super.toByteArray()
}
}.toByteArray(), encryptionKey))
}
}
/**
* @author Him188moe
*/

View File

@ -1,8 +1,7 @@
package net.mamoe.mirai.network.packet.client.session
package net.mamoe.mirai.network.packet.login
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.*
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.util.ClientLoginStatus
/**

View File

@ -1,11 +1,7 @@
package net.mamoe.mirai.network.packet.client.login
package net.mamoe.mirai.network.packet.login
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.ClientPacket
import net.mamoe.mirai.network.packet.client.writeHex
import net.mamoe.mirai.network.packet.client.writeQQ
import net.mamoe.mirai.network.packet.client.writeVarInt
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.util.ByteArrayDataOutputStream
import net.mamoe.mirai.util.TEACryptor

View File

@ -1,6 +1,6 @@
package net.mamoe.mirai.network.packet.server.login
package net.mamoe.mirai.network.packet.login
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.ServerPacket
import java.io.DataInputStream
/**

View File

@ -1,10 +1,10 @@
package net.mamoe.mirai.network.packet.server.login
package net.mamoe.mirai.network.packet.login
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.goto
import net.mamoe.mirai.network.packet.server.readNBytes
import net.mamoe.mirai.network.packet.server.readVarString
import net.mamoe.mirai.network.packet.ServerPacket
import net.mamoe.mirai.network.packet.goto
import net.mamoe.mirai.network.packet.readNBytes
import net.mamoe.mirai.network.packet.readVarString
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.TestedSuccessfully
import net.mamoe.mirai.util.hexToBytes

View File

@ -1,9 +1,9 @@
package net.mamoe.mirai.network.packet.server.login
package net.mamoe.mirai.network.packet.login
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.dataInputStream
import net.mamoe.mirai.network.packet.server.goto
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.util.TEACryptor
import net.mamoe.mirai.util.TestedSuccessfully
import net.mamoe.mirai.util.hexToUBytes

View File

@ -1,8 +1,8 @@
package net.mamoe.mirai.network.packet.server.login
package net.mamoe.mirai.network.packet.login
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.dataInputStream
import net.mamoe.mirai.network.packet.server.goto
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.util.TEACryptor
import java.io.DataInputStream

View File

@ -1,6 +1,6 @@
package net.mamoe.mirai.network.packet.server.security
package net.mamoe.mirai.network.packet.login
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.ServerPacket
import java.io.DataInputStream
/**

View File

@ -1,12 +0,0 @@
package net.mamoe.mirai.network.packet.server
import java.io.DataInputStream
/**
* @author Him188moe
*/
class UnknownPacket(input: DataInputStream) : ServerPacket(input) {
override fun decode() {
}
}

View File

@ -1,30 +0,0 @@
package net.mamoe.mirai.network.packet.server.security
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.dataInputStream
import net.mamoe.mirai.network.packet.server.goto
import net.mamoe.mirai.util.TEACryptor
import java.io.DataInputStream
/**
* @author Him188moe
*/
class ServerSKeyResponsePacket(input: DataInputStream) : ServerPacket(input) {
lateinit var sKey: String
override fun decode() {
this.sKey = String(this.input.goto(4).readNBytes(10))
}
}
class ServerSKeyResponsePacketEncrypted(inputStream: DataInputStream) : ServerPacket(inputStream) {
override fun decode() {
}
fun decrypt(sessionKey: ByteArray): ServerSKeyResponsePacket {
this.input goto 14
val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }
return ServerSKeyResponsePacket(TEACryptor.decrypt(data, sessionKey).dataInputStream());
}
}

View File

@ -1,66 +0,0 @@
package net.mamoe.mirai.network.packet.server.security
import net.mamoe.mirai.network.packet.client.writeHex
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.dataInputStream
import net.mamoe.mirai.network.packet.server.goto
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.lazyEncode
import java.io.DataInputStream
/**
* Dispose_0828
*
* @author Him188moe
*/
class ServerSessionKeyResponsePacket(inputStream: DataInputStream, val dataLength: Int) : ServerPacket(inputStream) {
lateinit var sessionKey: ByteArray
lateinit var tlv0105: ByteArray
@ExperimentalUnsignedTypes
override fun decode() {
when (dataLength) {
407 -> {
input goto 25
sessionKey = input.readNBytes(16)
}
439 -> {
input.goto(63)
sessionKey = input.readNBytes(16)
}
512,
527 -> {
input.goto(63)
sessionKey = input.readNBytes(16)
tlv0105 = lazyEncode {
it.writeHex("01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00")
input.goto(dataLength - 122)
it.write(input.readNBytes(56))
it.writeHex("00 40 02 02 03 3C 01 03 00 00")
input.goto(dataLength - 55)
it.write(input.readNBytes(56))
} //todo 这个 tlv0105似乎可以保存起来然后下次登录时使用.
}
else -> throw IllegalArgumentException(dataLength.toString())
}
//tlv0105 = "01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00" + 取文本中间(data, 取文本长度(data) 367, 167) “00 40 02 02 03 3C 01 03 00 00 ” 取文本中间 (data, 取文本长度 (data) 166, 167)
}
}
class ServerSessionKeyResponsePacketEncrypted(inputStream: DataInputStream) : ServerPacket(inputStream) {
override fun decode() {
}
fun decrypt(_0828_rec_decr_key: ByteArray): ServerSessionKeyResponsePacket {
this.input goto 14
val data = this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }
return ServerSessionKeyResponsePacket(TEACryptor.decrypt(data, _0828_rec_decr_key).dataInputStream(), data.size);
}
}

View File

@ -1,74 +0,0 @@
package net.mamoe.mirai.network.packet.server.touch
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.readIP
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.getRandomKey
import net.mamoe.mirai.util.hexToBytes
import net.mamoe.mirai.util.toUHexString
import java.io.DataInputStream
/**
* 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
*
* @author Him188moe
*/
class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) {
var serverIP: String? = null;
var loginTime: Int = 0
lateinit var loginIP: String
lateinit var token0825: ByteArray
lateinit var tgtgtKey: ByteArray
enum class Type {
TYPE_08_25_31_01,
TYPE_08_25_31_02,
}
@ExperimentalUnsignedTypes
override fun decode() {
when (val id = input.readByte().toUByte().toInt()) {
0xFE -> {
input.skip(94)
serverIP = input.readIP()
}
0x00 -> {
input.skip(4)
token0825 = input.readNBytes(56)
input.skip(6)
loginTime = input.readInt()
loginIP = input.readIP()
tgtgtKey = getRandomKey(16)
}
else -> {
throw IllegalStateException(arrayOf(id.toUByte()).toUByteArray().toUHexString())
}
}
}
}
class ServerTouchResponsePacketEncrypted(private val type: ServerTouchResponsePacket.Type, inputStream: DataInputStream) : ServerPacket(inputStream) {
override fun decode() {
}
@ExperimentalUnsignedTypes
fun decrypt(): ServerTouchResponsePacket {
input.skip(7)
var bytes = input.readAllBytes();
bytes = bytes.copyOfRange(0, bytes.size - 1);
println(bytes.toUByteArray().toUHexString())
return ServerTouchResponsePacket(DataInputStream(TEACryptor.decrypt(bytes, when (type) {
ServerTouchResponsePacket.Type.TYPE_08_25_31_02 -> Protocol.redirectionKey.hexToBytes()
ServerTouchResponsePacket.Type.TYPE_08_25_31_01 -> Protocol._0825key.hexToBytes()
}).inputStream()));
}
}

View File

@ -1,8 +1,8 @@
package net.mamoe.mirai.network.packet.server.login
package net.mamoe.mirai.network.packet.verification
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.dataInputStream
import net.mamoe.mirai.network.packet.server.goto
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.util.TEACryptor
import java.io.DataInputStream

View File

@ -1,7 +1,7 @@
package net.mamoe.mirai.util
import net.mamoe.mirai.network.packet.client.ClientPacket
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.ClientPacket
import net.mamoe.mirai.network.packet.ServerPacket
/**
* @author Him188moe

View File

@ -1,4 +1,4 @@
import net.mamoe.mirai.network.packet.client.login.ClientPasswordSubmissionPacket
import net.mamoe.mirai.network.packet.login.ClientPasswordSubmissionPacket
import net.mamoe.mirai.util.toUHexString
@ExperimentalUnsignedTypes
@ -42,6 +42,6 @@ fun main(){
packet.verifyCode.inputStream().transferTo(FileOutputStream(System.getProperty("user.dir") + "/5.png"))
*/
val packet = ClientPasswordSubmissionPacket(1994701021,"xiaoqqq",131513,"123.123.123.123","tgtgtKey".toByteArray(),"".toByteArray())
val packet = ClientPasswordSubmissionPacket(1994701021, "xiaoqqq", 131513, "123.123.123.123", "tgtgtKey".toByteArray(), "".toByteArray())
packet.encodeToByteArray().toUByteArray().toUHexString(" ")
}