This commit is contained in:
liujiahua123123 2019-08-23 11:25:38 +08:00
commit 8b5479f544
17 changed files with 511 additions and 333 deletions

1
.gitignore vendored
View File

@ -30,5 +30,4 @@ mirai.iml
.idea/*
/.idea/*
test/
/test

View File

@ -21,21 +21,10 @@
</parent>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.mina/mina-filter-ssl -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-filter-ssl</artifactId>
<version>1.1.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.mina/mina-filter-compression -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-filter-compression</artifactId>
<version>2.1.3</version>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
</dependency>
<dependency>

View File

@ -128,7 +128,7 @@ public class MiraiServer {
MiraiConfigSection<MiraiConfigSection> x = this.qqs.getTypedSection("test");
System.out.println(x.getSection("1").getInt("1"));
//System.out.println(x.getSection("1").getInt("1"));
/*
System.out.println(v);
@ -136,7 +136,6 @@ public class MiraiServer {
System.out.println(v.get("1111"));
*/
System.exit(0);
Robot robot = new Robot(1994701021, "xiaoqqq");
try {

View File

@ -22,4 +22,12 @@ class QQ(number: Int) : Contact(number) {
fun at(): String {
return "[@$number]"
}
/*
Make that we can use (QQ + QQ2 + QQ3).sendMessage( )
operator fun plus(qq: QQ): QQCombination {
}*/
}

View File

@ -1,150 +0,0 @@
package net.mamoe.mirai.network;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.DatagramSessionConfig;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
import java.io.IOException;
import java.net.*;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class MemoryMonitorTest {
private static final long serialVersionUID = 1L;
public static final int PORT = 8080;
public MemoryMonitorTest() throws IOException {
NioDatagramAcceptor acceptor = new NioDatagramAcceptor();//创建一个UDP的接收器
acceptor.setHandler(new YourHandler());//设置接收器的处理程序
Executor threadPool = Executors.newFixedThreadPool(1500);//建立线程池
acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
DatagramSessionConfig dcfg = acceptor.getSessionConfig();//建立连接的配置文件
dcfg.setReadBufferSize(4096);//设置接收最大字节默认2048
dcfg.setReceiveBufferSize(1024);//设置输入缓冲区的大小
dcfg.setSendBufferSize(1024);//设置输出缓冲区的大小
dcfg.setReuseAddress(true);//设置每一个非主监听连接的端口可以重用
acceptor.bind(new InetSocketAddress(PORT));//绑定端口
}
public static void main(String[] args) throws IOException {
new MemoryMonitorTest();
}
public class YourHandler extends IoHandlerAdapter {
//messageSent是Server响应给Clinet成功后触发的事件
@Override
public void messageSent(IoSession session, Object message) throws Exception {
if (message instanceof IoBuffer) {
IoBuffer buffer = (IoBuffer) message;
byte[] bb = buffer.array();
for (int i = 0; i < bb.length; i++) {
System.out.print((char) bb[i]);
}
}
}
//抛出异常触发的事件
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
cause.printStackTrace();
session.close(true);
}
//Server接收到UDP请求触发的事件
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
System.out.println("messageReceived");
if (message instanceof IoBuffer) {
IoBuffer buffer = (IoBuffer) message;
// byte[] bb = buffer.array();
// for(int i=0;i<bb.length;i++) {
// System.out.print((char)bb[i]);
// }
IoBuffer buffer1 = IoBuffer.wrap("11".getBytes());//返回信息给Clinet端
session.write(buffer1);
//声明这里message必须为IoBuffer类型
}
}
//连接关闭触发的事件
@Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("Session closed...");
}
//建立连接触发的事件
@Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println("Session created...");
SocketAddress remoteAddress = session.getRemoteAddress();
System.out.println(remoteAddress);
}
//会话空闲
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("Session idle...");
}
//打开连接触发的事件它与sessionCreated的区别在于一个连接地址A第一次请求Server会建立一个Session默认超时时间为1分钟此时若未达到超时时间这个连接地址A再一次向Server发送请求即是sessionOpened连接地址A第一次向Server发送请求或者连接超时后向Server发送请求时会同时触发sessionCreated和sessionOpened两个事件
@Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("Session Opened...");
SocketAddress remoteAddress = session.getRemoteAddress();
System.out.println(remoteAddress);
}
public void send(String host, int port) {
try {
InetAddress ia = InetAddress.getByName(host);
DatagramSocket socket = new DatagramSocket(9999);
socket.connect(ia, port);
byte[] buffer = new byte[1024];
buffer = ("22")
.getBytes();
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
System.out.println(dp.getLength());
DatagramPacket dp1 = new DatagramPacket(new byte[22312], 22312);
socket.send(dp);
socket.receive(dp1);
byte[] bb = dp1.getData();
for (int i = 0; i < dp1.getLength(); i++) {
System.out.print((char) bb[i]);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@ -68,9 +68,9 @@ class Robot(val number: Int, private val password: String) {
} else {//password submission
this.loginIP = packet.loginIP
this.loginTime = packet.loginTime
this.token0825 = packet.token
this.token0825 = packet.token0825
this.tgtgtKey = packet.tgtgtKey
sendPacket(ClientPasswordSubmissionPacket(this.number, this.password, packet.loginTime, packet.loginIP, packet.tgtgtKey, packet.token))
sendPacket(ClientPasswordSubmissionPacket(this.number, this.password, packet.loginTime, packet.loginIP, packet.tgtgtKey, packet.token0825))
}
}
@ -81,7 +81,7 @@ class Robot(val number: Int, private val password: String) {
}
is ServerLoginResponseVerificationCodePacket -> {
//[token00BA]可能来自这里
//[token00BA]来源之一: 验证码
this.token00BA = packet.token00BA
if (packet.unknownBoolean != null && packet.unknownBoolean!!) {
this.sequence = 1
@ -95,13 +95,17 @@ class Robot(val number: Int, private val password: String) {
sendPacket(ClientLoginSucceedConfirmationPacket(this.number, this.serverIP, this.loginIP, this.md5_32, packet.token38, packet.token88, packet.encryptionKey, this.tlv0105))
}
//这个有可能是客户端发送验证码之后收到的回复验证码是否正确?
//是ClientPasswordSubmissionPacket之后服务器回复的
is ServerLoginResponseResendPacket -> {
if (packet.token00BA != null) {
this.token00BA = packet.token00BA!!
println(token00BA)
}
if (packet.flag == ServerLoginResponseResendPacket.Flag.`08 36 31 03`) {
this.tgtgtKey = packet.tgtgtKey
sendPacket(ClientLoginResendPacket3104(this.number, this.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA))
sendPacket(ClientLoginResendPacket3104(this.number, this.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA, packet._0836_tlv0006_encr))
} else {
sendPacket(ClientLoginResendPacket3106(this.number, this.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA))
sendPacket(ClientLoginResendPacket3106(this.number, this.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA, packet._0836_tlv0006_encr))
}
}
@ -129,28 +133,27 @@ class Robot(val number: Int, private val password: String) {
e.printStackTrace()
}
packet.writeHex(Protocol.tail)
println(packet)
println(packet.toByteArray().toUByteArray().toHexString())
/*val p = DatagramPacket(packet.toByteArray());
p.socketAddress = this.serverAddress*/
//ctx.writeAndFlush(packet.toByteArray()).sync()
send(packet.toByteArray())
MiraiLogger info "Sending: $packet"
//GlobalScope.launch {
send(packet.toByteArray())
//}
//println(channel!!.writeAndFlush(packet.toByteArray()).channel().connect(serverAddress).sync().get())
MiraiLogger info "Packet sent: $packet"
}
private fun DatagramPacket(toByteArray: ByteArray): DatagramPacket = DatagramPacket(toByteArray, toByteArray.size, this.serverAddress)
// private val socket = DatagramSocket(15314)
@ExperimentalUnsignedTypes
fun send(data: ByteArray) {
try {
val socket = DatagramSocket((15314 + Math.random() * 5).toInt())
val socket = DatagramSocket((15314 + Math.random() * 10).toInt())
socket.connect(this.serverAddress)
val dp1 = DatagramPacket(ByteArray(22312), 22312)
socket.send(DatagramPacket(data, data.size))
MiraiLogger info "Packet sent: ${data.toUByteArray().toHexString()}"
socket.receive(dp1)
val zeroByte: Byte = 0
var i = dp1.data.size - 1;

View File

@ -41,7 +41,7 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
* Encode this packet.
*
*
* Before sending the packet, an [tail][Protocol.tail] will be added.
* Before sending the packet, a [tail][Protocol.tail] will be added.
*/
@Throws(IOException::class)
abstract fun encode()
@ -53,11 +53,12 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
}
override fun toString(): String {
return this.javaClass.simpleName + this.javaClass.declaredFields.joinToString(", ", "{", "}") { it.trySetAccessible(); it.name + "=" + it.get(this) }
return this.javaClass.simpleName + this.getAllDeclaredFields().joinToString(", ", "{", "}") { it.trySetAccessible(); it.name + "=" + it.get(this) }
}
}
@ExperimentalUnsignedTypes
@Throws(IOException::class)
fun DataOutputStream.writeIP(ip: String) {
for (s in ip.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
@ -99,6 +100,22 @@ fun DataOutputStream.writeVarInt(dec: UInt) {
throw UnsupportedOperationException()
}
fun DataOutputStream.encryptAndWrite(byteArray: ByteArray, key: ByteArray) {
this.write(TEACryptor.encrypt(byteArray, key))
}
fun DataOutputStream.encryptAndWrite(byteArray: ByteArray, cryptor: TEACryptor) {
this.write(cryptor.encrypt(byteArray))
}
fun DataOutputStream.encryptAndWrite(key: ByteArray, encoder: (ByteArrayDataOutputStream) -> Unit) {
this.write(TEACryptor.encrypt(ByteArrayDataOutputStream().let { encoder(it); it.toByteArray() }, key))
}
fun DataOutputStream.encryptAndWrite(cryptor: TEACryptor, encoder: (ByteArrayDataOutputStream) -> Unit) {
this.write(cryptor.encrypt(ByteArrayDataOutputStream().let { encoder(it); it.toByteArray() }))
}
@ExperimentalUnsignedTypes
@Throws(IOException::class)
fun DataOutputStream.writeTLV0006(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray) {
@ -111,40 +128,67 @@ fun DataOutputStream.writeTLV0006(qq: Int, password: String, loginTime: Int, log
val md5_1 = md5(password);
val md5_2 = md5(md5_1 + "00 00 00 00".hexToBytes() + qq.toByteArray())
println(md5_1.toUByteArray().toHexString())
println(md5_2.toUByteArray().toHexString())
it.write(md5_1)
it.writeInt(loginTime)//todo FIXED 12(maybe 11???) bytes??? check that
it.writeInt(loginTime)
it.writeByte(0);
it.writeZero(4 * 3)
it.writeIP(loginIP)
it.writeZero(8)
it.writeHex("00 10")
it.writeHex("15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B")
it.write(tgtgtKey)
this.write(TEACryptor.encrypt(md5_2, it.toByteArray()))
println()
println(it.toByteArray().toUHexString())
this.write(TEACryptor.encrypt(it.toByteArray(), md5_2))
}
}
@ExperimentalUnsignedTypes
fun DataOutputStream.writeCRC32() {
getRandomKey(16).let {
fun main() {
println(lazyEncode { it.writeTLV0006(1994701021, "D1 A5 C8 BB E1 Q3 CC DD", 131513, "123.123.123.123", "AA BB CC DD EE FF AA BB CC".hexToBytes()) }.toUByteArray().toHexString())
}
@ExperimentalUnsignedTypes
fun DataOutputStream.writeCRC32() = writeCRC32(getRandomKey(16))
@ExperimentalUnsignedTypes
fun DataOutputStream.writeCRC32(key: ByteArray) {
key.let {
write(it)//key
writeLong(getCrc32(it))//todo may be int? check that.
writeInt(getCrc32(it))
}
}
fun DataOutputStream.writeHostname() {
val hostName: String = InetAddress.getLocalHost().hostName.let { it.substring(0, it.length - 3) };
this.writeShort(hostName.length / 2);//todo check that
this.writeShort(hostName.length);
this.writeBytes(hostName)//todo 这个对吗?
fun DataOutputStream.writeDeviceName() {
val deviceName = InetAddress.getLocalHost().hostName
this.writeShort(deviceName.length + 2)
this.writeShort(deviceName.length)
this.writeBytes(deviceName)
}
fun Int.toByteArray(): ByteArray = byteArrayOf(//todo 检查这方法对不对, 这其实就是从 DataInputStream copy来的
/**
* 255 -> 00 00 00 FF
*/
fun Int.toByteArray(): ByteArray = byteArrayOf(
(this.ushr(24) and 0xFF).toByte(),
(this.ushr(16) and 0xFF).toByte(),
(this.ushr(8) and 0xFF).toByte(),
(this.ushr(0) and 0xFF).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.toHexString(separator: String = " "): String = this.toByteArray().toUByteArray().toHexString(separator);
@ -155,14 +199,14 @@ private fun md5(byteArray: ByteArray): ByteArray = MessageDigest.getInstance("MD
@ExperimentalUnsignedTypes
@Throws(IOException::class)
fun DataOutputStream.writeZero(count: Int) {
for (x in 0..count) {
repeat(count) {
this.writeByte(0)
}
}
@Throws(IOException::class)
fun DataOutputStream.writeRandom(length: Int) {
for (i in 0 until length) {
repeat(length) {
this.writeByte((Math.random() * 255).toInt().toByte().toInt())
}
}

View File

@ -3,10 +3,9 @@ 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.*
import net.mamoe.mirai.util.ByteArrayDataOutputStream
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.getRandomKey
import net.mamoe.mirai.util.hexToBytes
import net.mamoe.mirai.util.*
import java.io.DataOutputStream
import java.net.InetAddress
/**
* Password submission (0836_622)
@ -15,7 +14,14 @@ import net.mamoe.mirai.util.hexToBytes
*/
@PacketId("08 36 31 03")
@ExperimentalUnsignedTypes
class ClientPasswordSubmissionPacket(private val qq: Int, private val password: String, private val loginTime: Int, private val loginIP: String, private val tgtgtKey: ByteArray, private val token0825: ByteArray) : ClientPacket() {
class ClientPasswordSubmissionPacket(
private val qq: Int,
private val password: String,
private val loginTime: Int,
private val loginIP: String,
private val tgtgtKey: ByteArray,
private val token0825: ByteArray
) : ClientPacket() {
@ExperimentalUnsignedTypes
override fun encode() {
this.writeQQ(qq)
@ -24,26 +30,24 @@ class ClientPasswordSubmissionPacket(private val qq: Int, private val password:
this.writeHex("00 00 00 10")
this.writeHex(Protocol._0836key1)
this.write(TEACryptor.encrypt(object : ByteArrayDataOutputStream() {
override fun toByteArray(): ByteArray {
writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825)
writePart2()
return super.toByteArray()
}
}.toByteArray(), Protocol.shareKey.hexToBytes()))
this.encryptAndWrite(Protocol.shareKey.hexToBytes()) {
it.writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825)
it.writePart2()
println(it.toByteArray().toUHexString())
}
}
}
@PacketId("08 36 31 04")
@ExperimentalUnsignedTypes
class ClientLoginResendPacket3104(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray) : ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA)
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)
@PacketId("08 36 31 06")
@ExperimentalUnsignedTypes
class ClientLoginResendPacket3106(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray) : ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA)
class ClientLoginResendPacket3106(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)
@ExperimentalUnsignedTypes
open class ClientLoginResendPacket internal constructor(val qq: Int, val password: String, val loginTime: Int, val loginIP: String, val tgtgtKey: ByteArray, val token0825: ByteArray, val token00BA: ByteArray) : ClientPacket() {
open class ClientLoginResendPacket internal constructor(val qq: Int, val password: String, val loginTime: Int, val loginIP: String, val tgtgtKey: ByteArray, val token0825: ByteArray, val token00BA: ByteArray, val tlv_0006_encr: ByteArray? = null) : ClientPacket() {
override fun encode() {
this.writeQQ(qq)
this.writeHex(Protocol._0836_622_fix1)
@ -53,7 +57,7 @@ open class ClientLoginResendPacket internal constructor(val qq: Int, val passwor
this.write(TEACryptor.encrypt(object : ByteArrayDataOutputStream() {
override fun toByteArray(): ByteArray {
writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825)
this.writePart1(qq, password, loginTime, loginIP, tgtgtKey, token0825, tlv_0006_encr)
this.writeHex("01 10") //tag
this.writeHex("00 3C")//length
@ -61,13 +65,17 @@ open class ClientLoginResendPacket internal constructor(val qq: Int, val passwor
this.writeHex("00 38")//length
this.write(token00BA)//value
writePart2()
this.writePart2()
return super.toByteArray()
}
}.toByteArray(), Protocol.shareKey.hexToBytes()))
}
}
fun main() {
println(InetAddress.getLocalHost().hostAddress)
}
@ExperimentalUnsignedTypes
@PacketId("08 28 04 34")
class ClientLoginSucceedConfirmationPacket(
@ -112,7 +120,7 @@ class ClientLoginSucceedConfirmationPacket(
this.writeHex("68")
this.writeHex("00 00 00 00 00 2D 00 06 00 01")
this.writeIP(loginIP)//本地IP地址? todo test that
this.writeIP(InetAddress.getLocalHost().hostName)//? todo 这随便扔的
return super.toByteArray()
}
@ -124,14 +132,14 @@ class ClientLoginSucceedConfirmationPacket(
* @author Him188moe
*/
@ExperimentalUnsignedTypes
private fun ClientPacket.writePart1(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray) {
private fun DataOutputStream.writePart1(qq: Int, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, tlv_0006_encr: ByteArray? = null) {
this.writeQQ(System.currentTimeMillis().toInt())//that's correct
//this.writeInt(System.currentTimeMillis().toInt())
this.writeHex("01 12")//tag
this.writeHex("00 38")//length
this.write(token0825)//length
this.writeHex("03 0F")//tag
this.writeHostname()//todo 务必检查这个
this.writeDeviceName()
/*易语言源码: PCName就是HostName
PCName BytesToStr (Ansi转Utf8 (取主机名 ()))
PCName 取文本左边 (PCName, 取文本长度 (PCName) 3)*/
@ -140,7 +148,11 @@ private fun ClientPacket.writePart1(qq: Int, password: String, loginTime: Int, l
this.writeQQ(qq)
this.writeHex("00 06")//tag
this.writeHex("00 78")//length
this.writeTLV0006(qq, password, loginTime, loginIP, tgtgtKey)
if (tlv_0006_encr != null) {
this.write(tlv_0006_encr)
} else {
this.writeTLV0006(qq, password, loginTime, loginIP, tgtgtKey)
}
//fix
this.writeHex(Protocol._0836_622_fix2)
this.writeHex("00 1A")//tag
@ -160,7 +172,7 @@ private fun ClientPacket.writePart1(qq: Int, password: String, loginTime: Int, l
}
@ExperimentalUnsignedTypes
private fun ClientPacket.writePart2() {
private fun DataOutputStream.writePart2() {
this.writeHex("03 12")//tag
this.writeHex("00 05")//length

View File

@ -5,6 +5,7 @@ import net.mamoe.mirai.network.packet.client.toHexString
import net.mamoe.mirai.network.packet.server.login.*
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacket
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacketEncrypted
import net.mamoe.mirai.util.getAllDeclaredFields
import net.mamoe.mirai.util.toHexString
import java.io.DataInputStream
@ -32,7 +33,9 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
when (bytes.size) {
271, 207 -> return ServerLoginResponseResendPacketEncrypted(stream, when (idBytes) {
"08 36 31 03" -> ServerLoginResponseResendPacket.Flag.`08 36 31 03`
else -> ServerLoginResponseResendPacket.Flag.OTHER
else -> {
println("flag=$idBytes"); ServerLoginResponseResendPacket.Flag.OTHER
}
})
871 -> return ServerLoginResponseVerificationCodePacket(stream, bytes.size)
}
@ -48,14 +51,126 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
263 -> ServerLoginResponseFailedPacket.State.UNKNOWN_QQ_NUMBER
551, 487 -> ServerLoginResponseFailedPacket.State.DEVICE_LOCK
359 -> ServerLoginResponseFailedPacket.State.TAKEN_BACK
else -> throw IllegalStateException()
//unknown
63 -> throw IllegalArgumentException(bytes.size.toString())
351 -> throw IllegalArgumentException(bytes.size.toString())
else -> throw IllegalArgumentException(bytes.size.toString())
}, stream)
}
/*
TEA 加密, 内容=78 69 61 6F 71 71 71 00
g_count = 0
serverip = 220.249.245.140
TEA 加密, 内容=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 DC F9 F5 8C 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
paccket sent: 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 8F DA BC 2A AA 65 0B 87 9B 61 59 3D 91 2C F8 BA DE C5 38 18 F1 85 4B 4E AF 93 62 48 62 98 FD 0D B3 50 EA B9 F3 9A C1 8F 94 9E AD D1 D4 A7 37 CD 1F 49 C4 98 47 FE 4F 49 A3 99 50 82 89 A2 79 B2 EA BE 84 15 88 DC 01 90 B5 CE F1 C6 2F 40 59 03 29 87 1F 1A C8 D0 19 84 71 35 74 E3 47 78 A9 73 EC 86 C5 1F EA 6A 58 B4 03
DataArrived >>
DataArrived >> flag = 08 25 31 01
DataArrived >> dispose_0825 >>
DataArrived >> dispose_0825 >> redirect
DataArrived >> dispose_0825 >> g_server = 123.151.77.229
DataArrived >> dispose_0825 >> g_count = 0
DataArrived >> dispose_0825 >> TEA 加密, 内容=00 18 00 16 00 01 00 00 04 53 00 00 00 01 00 00 15 85 76 E4 B8 DD 00 01 00 00 03 09 00 0C 00 01 7B 97 4D E5 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 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
DataArrived >> dispose_0825 >> paccket sent: 02 37 13 08 25 31 02 76 E4 B8 DD 03 00 00 00 01 2E 01 00 00 68 52 00 00 00 00 A8 F2 14 5F 58 12 60 AF 07 63 97 D6 76 B2 1A 3B D7 05 E8 5C C1 F4 3D 0E D5 09 03 47 FE 9C 63 C0 7B BA 12 09 90 94 8C 8A FA 63 44 D6 C5 4D 45 BC 4B B5 E4 F9 FA A2 7B FC 00 C6 38 05 6E 00 7D 5C 23 A9 56 3D 0C 85 A0 99 6C 96 3C 31 A0 E9 FE E0 EA 01 0B 96 17 E8 B4 2A 11 BB 16 20 76 F8 AF 65 53 E1 A3 AA 72 BC FB 50 F3 5C DB 35 B6 89 F0 2C C5 C9 47 84 E2 56 CD 1E B3 E9 35 1E 09 A6 E1 56 03
DataArrived >>
DataArrived >> flag = 08 25 31 02
DataArrived >> dispose_0825 >>
DataArrived >> dispose_0825 >> g_count = 0
DataArrived >> dispose_0825 >> 不需要redirect
DataArrived >> dispose_0825 >> m_loginTime = 5D 5D 6C 21
DataArrived >> dispose_0825 >> m_loginIP = 1B 12 55 CB
DataArrived >> dispose_0825 >> m_0825token = D5 CC FC 5E BF 39 4C 07 7F FF AE 3C C2 10 E0 0E 3D C1 7B 6C 1C 58 9C 97 AB DE DC 4C B7 8E AB DA 77 BE 5F AD 8D 3C EA 7D B8 3D 5E B3 5B 6B DD 32 E6 A5 0C 6F B7 93 E4 C3
DataArrived >> dispose_0825 >> m_tgtgtKey = F5 0D 99 8B FE E8 B6 D8 0A 3D D3 37 B0 D2 9C 63
DataArrived >> dispose_0825 >> g_count = 0
DataArrived >> dispose_0825 >> Construct_0836_622 >>
DataArrived >> dispose_0825 >> Construct_0836_622 >> PCName = DESKTOP-M17JREU
DataArrived >> dispose_0825 >> Construct_0836_622 >> PCName = 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55
DataArrived >> dispose_0825 >> Construct_0836_622 >> g_pass = xiaoqqq
DataArrived >> dispose_0825 >> Construct_0836_622 >> g_QQ = 76 E4 B8 DD
DataArrived >> dispose_0825 >> Construct_0836_622 >> crc32_code(Random) = B9 3F 9E D7 6A 6E 92 33 96 1A 49 8D 0C 2B 4E B6
DataArrived >> dispose_0825 >> Construct_0836_622 >> crc32_data = 8E B3 B0 95
DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >>
DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >> m_tgtgtKey = F5 0D 99 8B FE E8 B6 D8 0A 3D D3 37 B0 D2 9C 63
DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >> packet = 73 64 FA 6A 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 95 5B 96 CB 95 CF 1C A6 94 C4 B7 79 07 9A BB 15 5D 5D 6C 21 00 00 00 00 00 00 00 00 00 00 00 00 00 1B 12 55 CB 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B F5 0D 99 8B FE E8 B6 D8 0A 3D D3 37 B0 D2 9C 63
DataArrived >> dispose_0825 >> Construct_0836_622 >> TEA 加密, 内容=73 64 FA 6A 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 95 5B 96 CB 95 CF 1C A6 94 C4 B7 79 07 9A BB 15 5D 5D 6C 21 00 00 00 00 00 00 00 00 00 00 00 00 00 1B 12 55 CB 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B F5 0D 99 8B FE E8 B6 D8 0A 3D D3 37 B0 D2 9C 63
DataArrived >> dispose_0825 >> Construct_0836_622 >> TEA 加密, 内容=00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B
DataArrived >> dispose_0825 >> Construct_0836_622 >> TEA 加密, 内容=01 12 00 38 D5 CC FC 5E BF 39 4C 07 7F FF AE 3C C2 10 E0 0E 3D C1 7B 6C 1C 58 9C 97 AB DE DC 4C B7 8E AB DA 77 BE 5F AD 8D 3C EA 7D B8 3D 5E B3 5B 6B DD 32 E6 A5 0C 6F B7 93 E4 C3 03 0F 00 11 00 0F 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55 00 05 00 06 00 02 76 E4 B8 DD 00 06 00 78 A3 54 98 4E 29 8F D5 90 5F 8E DC 2D 8F 89 FB B2 F5 60 BF 7D 4E D4 13 7D 77 81 9A 49 C6 4A D9 78 4A AB 30 B2 24 FD CF D2 64 15 54 5E 1E 84 6F B2 78 E6 B4 E7 52 2F AB 89 61 D2 B7 50 C4 D3 DA F2 A8 C2 66 5D E7 24 52 D7 81 91 E2 35 77 DD 83 46 10 83 52 18 3C 02 39 9B BF B8 C5 DA 86 4F 9D A9 C4 A9 E0 AC 6E 5A ED C8 D6 33 09 82 FF 91 5D 85 B0 18 37 A4 5F A2 8D 32 00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B 00 1A 00 40 11 8F F8 25 B6 45 D5 69 FE E9 8C 8D E1 FA BE D2 68 BD 69 14 E7 24 9A 9B 2C 54 14 8E 33 57 17 3A 9C 7C EB EF F1 08 46 35 5F 64 2F 85 59 DC 3F 71 D2 62 CD 4E EB 80 B8 A3 1D B0 39 F7 2B 60 F1 2D 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 01 03 00 14 00 01 00 10 60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6 03 12 00 05 01 00 00 00 01 05 08 00 05 01 00 00 00 00 03 13 00 19 01 01 02 00 10 04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA 00 00 00 00 01 02 00 62 00 01 04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48 00 38 E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3 00 14 B9 3F 9E D7 6A 6E 92 33 96 1A 49 8D 0C 2B 4E B6 8E B3 B0 95
DataArrived >> dispose_0825 >> Construct_0836_622 >>
DataArrived >> dispose_0825 >> Construct_0836_622 >> PCName = DESKTOP-M17JREU
DataArrived >> dispose_0825 >> Construct_0836_622 >> PCName = 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55
DataArrived >> dispose_0825 >> Construct_0836_622 >> g_pass = xiaoqqq
DataArrived >> dispose_0825 >> Construct_0836_622 >> g_QQ = 76 E4 B8 DD
DataArrived >> dispose_0825 >> Construct_0836_622 >> crc32_code(Random) = D4 AE 9F 12 F0 50 A7 C7 0F 29 A3 E3 36 5C 3E D0
DataArrived >> dispose_0825 >> Construct_0836_622 >> crc32_data = 4E C5 09 4F
DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >>
DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >> m_tgtgtKey = F5 0D 99 8B FE E8 B6 D8 0A 3D D3 37 B0 D2 9C 63
DataArrived >> dispose_0825 >> Construct_0836_622 >> getTLV0006 >> packet = D4 13 A0 EE 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 95 5B 96 CB 95 CF 1C A6 94 C4 B7 79 07 9A BB 15 5D 5D 6C 21 00 00 00 00 00 00 00 00 00 00 00 00 00 1B 12 55 CB 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B F5 0D 99 8B FE E8 B6 D8 0A 3D D3 37 B0 D2 9C 63
DataArrived >> dispose_0825 >> Construct_0836_622 >> TEA 加密, 内容=D4 13 A0 EE 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 95 5B 96 CB 95 CF 1C A6 94 C4 B7 79 07 9A BB 15 5D 5D 6C 21 00 00 00 00 00 00 00 00 00 00 00 00 00 1B 12 55 CB 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B F5 0D 99 8B FE E8 B6 D8 0A 3D D3 37 B0 D2 9C 63
DataArrived >> dispose_0825 >> Construct_0836_622 >> TEA 加密, 内容=00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B
DataArrived >> dispose_0825 >> Construct_0836_622 >> TEA 加密, 内容=01 12 00 38 D5 CC FC 5E BF 39 4C 07 7F FF AE 3C C2 10 E0 0E 3D C1 7B 6C 1C 58 9C 97 AB DE DC 4C B7 8E AB DA 77 BE 5F AD 8D 3C EA 7D B8 3D 5E B3 5B 6B DD 32 E6 A5 0C 6F B7 93 E4 C3 03 0F 00 11 00 0F 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55 00 05 00 06 00 02 76 E4 B8 DD 00 06 00 78 0B FA 95 C5 8F 80 27 7B 8B 80 F9 66 96 32 12 5E C3 B4 22 C3 37 6D 06 05 1D 9F 75 83 D4 51 D9 55 18 32 22 49 45 3B 0E 1C 84 B9 0A 25 90 19 2B B5 16 97 4B 5A 82 10 4A C2 DE CF A8 A1 79 5C BF 4E 40 62 08 AE A5 C6 7D 15 12 19 8E 7C 2F 3C 72 8B EB 0C 87 79 42 27 4D EE 4B EF E6 3C 43 59 87 EE BF D9 06 D0 85 61 A0 BA 4A E6 07 D5 9B 02 21 AA D0 81 4A 75 57 6D D9 40 00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B 00 1A 00 40 0E BA 4A 1E D7 E3 BB F1 A8 08 19 18 A8 B4 34 54 56 9E 9C 4D D6 C0 37 D7 64 53 90 23 F0 2C 31 E4 BB DE 9B 2B 65 24 71 0A 39 5E 84 23 C6 92 CB E6 79 9B 64 01 18 3C 9F 6F B1 09 AF 54 63 A0 89 0E 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 01 03 00 14 00 01 00 10 60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6 03 12 00 05 01 00 00 00 01 05 08 00 05 01 00 00 00 00 03 13 00 19 01 01 02 00 10 04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA 00 00 00 00 01 02 00 62 00 01 04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48 00 38 E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3 00 14 D4 AE 9F 12 F0 50 A7 C7 0F 29 A3 E3 36 5C 3E D0 4E C5 09 4F
DataArrived >> dispose_0825 >> paccket sent: 02 37 13 08 36 31 03 76 E4 B8 DD 03 00 00 00 01 01 01 00 00 68 20 00 00 00 00 00 01 01 03 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 00 00 00 10 EF 4A 36 6A 16 A8 E6 3D 2E EA BD 1F 98 C1 3C DA A4 97 7E 14 53 79 9E 19 26 25 78 B7 FD 79 0C F7 F9 34 4A 1C 14 32 CF DE 10 4F 79 00 02 B9 65 0D 62 AA 27 47 86 35 0D 1D D4 A7 67 AC 9B D8 65 75 8F 83 CB D5 AC 48 2F 9C 5C 6C 35 87 57 C9 18 0A 54 23 0C D2 28 15 75 45 52 0B B7 D6 63 B1 0A 55 AE 27 E1 B3 C5 F8 4F 06 EF 1D 02 EC 5E 58 81 89 62 C0 38 DF 8D F8 C0 A8 26 4C B7 FE 2A E9 05 06 F5 33 D4 1C B9 09 D1 BB 32 6E 76 63 D1 E6 7F CF 21 AB BA 22 BF A8 78 5D B7 5D F2 DC C8 B0 E5 B9 21 09 1B 5A C0 9A 8D 21 88 D6 7B 2C 72 E5 7B E2 E8 EA 68 D5 52 2E 6F ED CC 9A DF C9 D0 0A 58 B3 84 B6 0F 1F 9E 03 89 BE 5A 11 52 C4 64 D1 69 51 77 4C AB 03 E8 69 DA 21 8A 82 86 22 64 78 25 B8 55 D7 71 15 97 A4 66 AD 6A 6E C9 64 01 55 40 24 15 35 6D A8 3E 2D BA 1B 0B 0F FF D3 40 AB C0 E0 21 B7 3E 28 EA B9 11 AB 30 5E B3 13 C9 32 FE FF 33 83 83 6B 63 7F 83 32 20 8B 85 DD 88 F4 0F 55 1C 71 0B 61 AC FE 20 19 D1 DD B3 5E 1D 5D 49 6F 0C 37 D8 39 25 D0 C1 15 94 34 82 F6 FC 76 25 8F 37 61 02 62 F3 BE 35 B5 3B F4 73 35 5B EF 15 70 6D 43 10 8E C9 4E DE 69 49 6A 0D 19 3A 1D 00 18 2F 8D 35 63 4A 66 06 23 74 2F DF C0 9E 0E F7 1E 07 A5 9F D5 05 0C 92 EB 4D 0E CA 64 E3 62 2A 0C 08 73 A8 38 E9 BA 7F B2 EE 4A 79 B8 47 33 88 00 06 28 40 81 25 59 65 0C 2D 16 36 CC A5 A7 E6 A0 7D 4C 33 16 79 60 48 74 8E 64 B1 46 56 59 E9 E5 CE 11 F5 D2 18 61 73 7F 25 9D 38 66 18 16 5F 1F A7 2A CA 08 95 C9 1B F3 83 7E 6F 01 9C F3 B0 65 C2 48 B1 0F 38 CB D2 B1 46 76 96 40 81 CA 1F AB 23 CB 98 CE 31 EB 62 0D DF EB 8A EC E4 30 53 92 0A 40 A7 D6 93 BD 83 E5 48 77 66 51 01 86 FE 5A 1D 7D 1A 2E A0 0F A5 FC B3 FD B2 B6 DF 79 17 8E 25 43 B7 D7 52 63 93 A3 CF 1A 3D B1 D8 02 F2 37 4B 2B 91 1A AC 9C EB 3E D0 71 34 95 F3 59 7C 88 03
DataArrived >>
DataArrived >> flag = 08 36 31 03
DataArrived >> Dispose_0836 >>
DataArrived >> Dispose_0836 >> g_count = 0
DataArrived >> Dispose_0836 >> Construct_0836_686 >>
DataArrived >> Dispose_0836 >> Construct_0836_686 >> TEA 加密, 内容=00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B
DataArrived >> Dispose_0836 >> Construct_0836_686 >> TEA 加密, 内容=01 12 00 38 D5 CC FC 5E BF 39 4C 07 7F FF AE 3C C2 10 E0 0E 3D C1 7B 6C 1C 58 9C 97 AB DE DC 4C B7 8E AB DA 77 BE 5F AD 8D 3C EA 7D B8 3D 5E B3 5B 6B DD 32 E6 A5 0C 6F B7 93 E4 C3 03 0F 00 11 00 0F 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55 00 05 00 06 00 02 76 E4 B8 DD 00 06 00 78 64 5C 48 D5 BF 98 6A 81 8F B5 09 DA A5 83 0E 45 BB 99 9B 03 42 2A 87 95 48 88 52 0D 5F 0B C1 4D A7 5F BF 60 4F 3D A1 04 D3 B4 E4 D2 45 71 5C 74 95 80 86 45 E0 26 EA B2 B1 09 0B 56 22 68 7C 5D 8D 9E 69 E4 C5 4E 0C EA F5 6F 90 FF 4B 43 43 EB 4F 76 45 70 DA 12 C7 1E A5 14 B8 5B 78 79 75 5E 2C F3 5D 1A C4 39 D5 AE 1A 70 EC AF A1 F5 FF D6 D3 B9 C6 DA 71 7E 15 52 00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B 00 1A 00 40 9D AB 45 74 6A E5 3F E2 8E 81 16 6C BB FA 0D A1 37 28 2F B9 02 3D EB 07 C7 ED 95 99 F9 35 27 35 58 67 4A FA 6E E4 89 37 8A 00 3B 19 C5 15 7E F6 83 D5 CF 66 9C FD 10 9F 27 90 31 3B 2E 98 F9 4C 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 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 10 00 3C 00 01 00 38 3A 51 49 BC 3C 44 78 A1 A7 6D B7 98 03 05 9F 42 E1 15 E5 53 0C C1 03 82 5E AE AD FC 44 C6 E9 85 66 51 F2 E2 67 B4 60 DC 89 EC E4 56 13 52 E6 AA C4 5A D1 FA 3D E7 10 92 03 12 00 05 01 00 00 00 01 05 08 00 05 01 00 00 00 00 03 13 00 19 01 01 02 00 10 04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA 00 00 00 00 01 02 00 62 00 01 04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48 00 38 E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3 00 14 D5 4E 31 3E 5E B3 28 6C 94 FB 25 CA E8 C4 A4 28 09 02 B2 58
DataArrived >> Dispose_0836 >> paccket sent: 02 37 13 08 36 31 04 76 E4 B8 DD 03 00 00 00 01 01 01 00 00 68 20 00 00 00 00 00 01 01 03 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 00 00 00 10 EF 4A 36 6A 16 A8 E6 3D 2E EA BD 1F 98 C1 3C DA 5B F1 07 07 6C A1 9E 91 11 46 45 D5 E8 58 B3 0D AB 1A B9 5E F3 F9 39 AE 1B A4 9C 9D 4F 46 3E 98 7D 53 63 6C 92 31 41 4D 41 56 BB 0D 4D 2C 4F 2A BB F1 71 FA 4E EA 90 5E B4 18 C1 50 AD F8 74 61 87 46 07 5D 2B 34 00 29 44 2C 40 C6 75 9C 28 F1 BC B8 25 DC 91 80 93 9E 4A 38 58 89 1B 98 61 26 2F 72 2D AA 72 1D E6 84 ED B5 8A AA 65 83 26 95 CE 33 4B 8F CD E4 B1 F5 06 E7 37 D5 D4 9A D8 59 62 99 86 E8 6C 1A 64 31 78 E5 FB B6 CF F4 1B 7C D8 09 D1 B0 E7 CC 2A EC 7E E0 C3 6B 9A AB B2 73 5E 42 4D 8A 42 C6 7D 8C 55 4F 7B 7F BD 1F C7 CC 68 A6 B1 36 69 BF AC F7 26 42 26 02 4D C1 D6 75 FB C1 DF 3C 2B 59 B3 46 D4 4A A4 D3 9F 11 BA 22 7C 59 67 72 37 A1 01 48 85 54 AA 9E 0A 18 B3 57 3C FD 85 CA 61 81 2A C2 F5 56 96 F1 D6 CA 3B 39 12 04 CC E7 AB 19 0C 83 ED DC 12 36 48 EE DE 9E 06 CA 86 8E FC E3 35 F8 81 DF 89 52 84 0F BA 3B 89 59 4A 5C 8E C4 D4 CD 07 D6 55 03 CC DC 67 D3 75 C3 F3 0E 77 7C 5D D3 11 EF 1B DB 39 EA 0F ED DE 38 C8 14 0E 4B 31 57 2B 79 B8 45 4B 04 FC 36 C6 6C 76 0B C5 4D 7B B1 35 BA 02 2C DB F9 2E 77 D6 76 8F A9 F1 3F 27 28 7F 14 0E 81 DB FF 7C 64 7B 0A 0C 52 C1 3B 7F 9E FB 78 71 7F 92 6C 2B A5 26 8D 5A ED BF C8 F3 C6 55 66 A3 BE E1 F0 C6 F3 BE D0 5A 6B B4 A7 6D 36 70 CE 81 B7 BA E3 00 01 64 28 B0 3E BE 17 01 53 A6 61 21 98 A2 5C 27 71 86 A6 68 A8 DD CC 62 85 8E EB 19 35 64 69 88 1A 2B 55 E8 06 EC 24 88 8F 5D E0 E1 24 DC 44 04 49 BA 74 6D 2A 8F 4B E3 97 8F A1 AA FE 19 3A 56 7B D4 29 18 D1 AE D4 D3 67 E9 64 4B F7 28 75 F1 8A C2 DF A5 0D 89 76 F1 89 9A 4A D3 89 24 63 CA 41 4A C1 54 84 DE 8E 91 62 4E 64 A2 A3 D0 74 4C ED 9F 45 EC E0 47 63 26 B4 CC F4 81 2C 86 0F 74 58 55 9C 57 45 7F CD 46 85 75 46 82 7D 44 0E E4 69 35 6F DB BD 29 45 56 31 5B A1 F3 D0 53 CA 21 4E 9F D7 A5 10 4E 27 9F B2 2D A9 E5 51 9C 37 1F 2E C0 5F DD 9F C6 F2 3F B3 40 B9 BD 43 DF 69 3A 9E EE 33 BF BC 97 48 CA 26 18 23 9F 53 09 28 AA 6D 03
DataArrived >>
DataArrived >> flag = 08 36 31 04
DataArrived >> Dispose_0836 >>
DataArrived >> Dispose_0836 >> m_0828_rec_decr_key = 6B 40 2C 37 5A 68 49 48 64 2A 65 56 73 45 39 7B
DataArrived >> Dispose_0836 >> nick_length = 20
DataArrived >> Dispose_0836 >> m_nick = (?ω)
DataArrived >> Dispose_0836 >> m_age = 5
DataArrived >> Dispose_0836 >> m_gender = 02
DataArrived >> Dispose_0836 >> g_clientKey = 00015D5D6C220068BAB85AE57EEF60E22609664CB355F10EBA5C1163F3D706D4515D00819BD314E94689CBBD75F16EA2C0898DFCBF4F2C893ED8D3C6481C97F6565597BC6A2C9C8FE8F54139A5D7B9729A31C2A8DC738FE4940D4935BF1417AA57452D7EE6AE7FFAF710B8A6EAA40B64
DataArrived >> Dispose_0836 >> token38 = 38 51 97 3C CB 14 37 E1 F0 6C 38 DA AD F0 77 1E AC 15 78 BD FE AD 47 BF CA 73 7E CA 54 33 6C 5F 85 D1 69 65 4E 38 F1 B7 08 69 03 AF D5 E6 D5 3D BC B6 32 94 4F 98 E0 CC
DataArrived >> Dispose_0836 >> token88 = 00 04 5D 5D 6C 22 1B 12 55 CB 00 00 00 00 00 78 68 37 FE F2 E2 2E 1C 31 E9 6D 77 DB C9 15 0C 82 49 56 E4 33 2B 84 E2 98 EB A6 25 33 2E AC A0 37 76 36 3C 8B E9 20 9B E1 97 0B EA 4E CF 41 C4 34 81 6C 51 03 07 C6 6C 7F A4 6C 6B 37 00 E5 C9 9B 57 8D 9F 74 6E E8 09 BF 44 D0 2F AD B6 A8 B9 6E DD F0 13 DB 87 59 69 BE 94 D9 4F 50 23 D1 87 9F B7 BC 9C 63 8E 09 3D 5E AB 9E 3C 93 CB 2D 26 50 9C 50 D6 7C 5E E4 47 44
DataArrived >> Dispose_0836 >> encryptionKey = 91 45 27 FB 09 3D BE 75 85 B9 E4 EB B7 B7 F8 38
DataArrived >> Dispose_0836 >> g_count = 0
DataArrived >> Dispose_0836 >> Construct_0828 >>
DataArrived >> Dispose_0836 >> Construct_0828 >> TEA 加密, 内容=00 07 00 88 00 04 5D 5D 6C 22 1B 12 55 CB 00 00 00 00 00 78 68 37 FE F2 E2 2E 1C 31 E9 6D 77 DB C9 15 0C 82 49 56 E4 33 2B 84 E2 98 EB A6 25 33 2E AC A0 37 76 36 3C 8B E9 20 9B E1 97 0B EA 4E CF 41 C4 34 81 6C 51 03 07 C6 6C 7F A4 6C 6B 37 00 E5 C9 9B 57 8D 9F 74 6E E8 09 BF 44 D0 2F AD B6 A8 B9 6E DD F0 13 DB 87 59 69 BE 94 D9 4F 50 23 D1 87 9F B7 BC 9C 63 8E 09 3D 5E AB 9E 3C 93 CB 2D 26 50 9C 50 D6 7C 5E E4 47 44 00 0C 00 16 00 02 00 00 00 00 00 00 00 00 00 00 7B 97 4D E5 1F 40 00 00 00 00 00 15 00 30 00 01 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 06 A9 12 97 B7 F8 76 25 AF AF D3 EA B4 C8 BC E7 00 36 00 12 00 02 00 01 00 00 00 05 00 00 00 00 00 00 00 00 00 00 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 00 1F 00 22 00 01 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 01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00 C2 D9 3F A5 A0 1B 6C 03 A2 EF AB CB 42 92 44 8E 15 97 28 1F DE B6 E9 0A 5C 53 01 CE A2 CC 95 3F E0 CB 30 3F 5C 67 09 22 83 CC 8A 80 8F D6 26 F5 EF EC 24 15 95 8E CE 99 00 40 02 02 03 3C 01 03 00 00 A1 4D 57 52 9E 5B 1F BB 48 75 09 67 F8 C0 64 F6 9B 2A 44 61 78 29 C1 26 9C 3C 59 0E DF 9B D1 59 97 0B 0C 2B 09 27 C6 7C 20 63 11 02 E1 4E A4 DE E2 59 CF A7 A1 47 0A B6 01 0B 00 85 00 02 B9 ED EF D7 CD E5 47 96 7A B5 28 34 CA 93 6B 5C 32 10 00 00 00 00 00 00 00 02 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 CC 1E A2 A7 AB 3B E4 05 27 F2 92 9B 9E 09 54 53 F9 21 86 78 D2 B0 AD 10 40 44 7F AA 2E F2 4E C0 68 00 00 00 00 00 2D 00 06 00 01 C0 A8 89 01
DataArrived >> Dispose_0836 >> paccket sent: 02 37 13 08 28 04 34 76 E4 B8 DD 02 00 00 00 01 2E 01 00 00 68 52 00 30 00 3A 00 38 38 51 97 3C CB 14 37 E1 F0 6C 38 DA AD F0 77 1E AC 15 78 BD FE AD 47 BF CA 73 7E CA 54 33 6C 5F 85 D1 69 65 4E 38 F1 B7 08 69 03 AF D5 E6 D5 3D BC B6 32 94 4F 98 E0 CC 78 DC 9A D7 2C EE 7E D6 16 55 15 39 B3 EF DF 3E 09 77 4A 3F 7E 60 08 C8 EC B0 22 52 53 1A FB DE 80 57 F3 97 DA B5 AF 20 E5 AF 9C 09 CF 0B 5C 46 0D 7D 32 DB 5A 59 88 A2 93 36 05 8F C6 5F C2 12 54 9C 5C 70 34 23 02 5E 28 C5 04 FF 88 3A 65 5C 9B E2 DC B4 16 F4 63 E6 4D 32 52 4A 0F 7A 3C 94 A2 4B EA 73 6C 64 DB AB CD FD 7A DB 23 4B 2B 38 F2 AE 46 29 03 CC A6 2C F2 BF 6F DD C8 27 E7 C5 F1 6C E4 0C 0B E4 A4 64 81 9F 6A 86 EE 1C 71 BA 96 65 67 CA 66 90 65 D4 6E CE 4D 4B 30 42 77 7D 88 F8 2D B8 8A 64 4B 41 E5 66 E0 27 17 14 80 08 BB 58 D9 A0 32 88 80 DD 25 38 AB 2D 56 88 3B 7C B3 1C 76 A1 4E 72 F4 FA 20 84 5B 60 58 A9 C5 34 DA BA 30 D5 D0 04 B4 38 83 E5 8B 0C AD DC AD D5 0D 74 46 79 4B E2 C9 5E 0C B6 79 34 30 92 DA BC 78 9D 28 1E 0C 3E 2F 5E 0E 51 89 2A A5 E6 75 94 ED C9 BB 0E 53 14 9A C6 4E 18 38 26 65 A5 96 BB 8C 9D 5F CF F2 8C 63 EA E5 C6 AC 6E BD 8B BD 9E 2C 12 4E CA 1D 92 3A 96 D8 23 C5 06 5D 5D 74 DA 41 F4 27 A5 3E FE 31 9F A0 8C 48 2F BA B7 EB 0D 74 6D 77 82 60 EA 97 BA DB 2D 1A 45 67 A6 F3 86 87 FD 2E 51 45 72 D9 66 C5 A0 17 B0 EC 66 00 5E 29 76 2C D9 23 F2 F7 83 20 22 22 D5 01 8E 56 FE AE CE F9 32 73 E1 E1 D4 D3 E0 AC E8 3C 78 0A A5 2A 1C 67 C0 ED C7 7D 2B 44 00 6B 79 6E 52 B8 5F 74 0A A1 18 3D 36 C7 17 23 AC C3 AC BC 38 20 AF 09 59 EF 6D E3 BC 4B F6 63 B0 00 25 D0 63 23 40 08 BC 4E 14 8B 76 6B 88 E7 D1 7C 9D E2 CD EA 2F 8A 1C 5D FE 58 E6 A8 13 9D EE 71 83 9F 25 0B 7C 15 93 9E B8 EA 3C 8C 5A C7 34 B0 0C 47 AA 4B E7 DC 1C 43 0F FF 9A 1F 3D 35 1A 3F 9F 7F 8C F5 03 E6 CC 0C 9C 34 89 F0 4A E8 44 F6 CE 37 61 B6 5F 50 64 B7 DA FA 96 70 8F 62 B6 E6 FC 24 0B FC E9 BA 7D E4 ED 3E 74 BE 73 C6 D3 69 8D 00 E7 E8 CD 56 CA AE 89 E5 C5 AB EE 2B BF 29 80 33 AE BE AC 58 01 B6 44 71 F1 97 BD BC A6 D1 A2 19 8B 8A 55 EC 97 13 99 5C 24 06 C7 0B 9B 1B A7 40 10 54 0D F1 96 69 46 97 E4 9C B2 88 8D 22 F4 2F 9A F7 B8 03
DataArrived >>
DataArrived >> flag = 08 28 04 34
DataArrived >> Dispose_0828 >>
DataArrived >> Dispose_0828 >> g_count = 0
DataArrived >> Dispose_0828 >> g_sessionKey = F9 FF 53 3B 4F 05 C5 14 E0 B0 73 E3 30 DD 13 05
DataArrived >> Dispose_0828 >> g_tlv0105 = 01 05 00 88 00 01 01 02 00 40 02 01 03 3C 01 03 00 00 C2 D9 3F A5 A0 1B 6C 03 A2 EF AB CB 42 92 44 8E 15 97 28 1F DE B6 E9 0A 5C 53 01 CE A2 CC 95 3F E0 CB 30 3F 5C 67 09 22 83 CC 8A 80 8F D6 26 F5 EF EC 24 15 95 8E CE 99 00 40 02 02 03 3C 01 03 00 00 A1 4D 57 52 9E 5B 1F BB 48 75 09 67 F8 C0 64 F6 9B 2A 44 61 78 29 C1 26 9C 3C 59 0E DF 9B D1 59 97 0B 0C 2B 09 27 C6 7C 20 63 11 02 E1 4E A4 DE E2 59 CF A7 A1 47 0A B6
DataArrived >> Dispose_0828 >> g_loginStatus = 0A
DataArrived >> Dispose_0828 >> TEA 加密, 内容=01 00 0A00 01 00 01 00 04 00 00 00 00
DataArrived >> Dispose_0828 >> paccket sent: 02 37 13 00 EC C6 05 76 E4 B8 DD 02 00 00 00 01 01 01 00 00 68 20 4B 3A FB 98 95 73 67 34 11 13 F4 36 88 21 AF 5D 3D AF C4 CD 60 42 2E 49 03
DataArrived >>
DataArrived >> flag = 00 EC C6 05
DataArrived >> g_count = 0
DataArrived >> TEA 加密, 内容=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
DataArrived >> paccket sent: 02 37 13 00 1D 4C 43 76 E4 B8 DD 02 00 00 00 01 01 01 00 00 68 20 3A 29 1D C9 D7 6F 28 7A EA CB FA 15 22 84 87 07 A1 DD 41 BA 96 CA 6E F5 57 AA 08 EC 7C E6 2E 15 68 0A A2 D5 1F F2 6B 63 3F 36 FD 86 8C 80 B1 2A DD 0F FE 81 BE 21 D4 62 A6 56 8C 4F BD 65 96 9C B0 1C 33 4D 58 5D 42 A8 2E 3E D1 A7 BD 3C BD 26 03
DataArrived >>
DataArrived >> flag = 00 1D 4C 43
DataArrived >> TEA 加密, 内容=88 76 E4 B8 DD 00
DataArrived >> paccket sent: 02 37 13 00 5C 41 99 76 E4 B8 DD 02 00 00 00 01 01 01 00 00 68 20 26 E8 D2 6B 7B 09 BA 3E B2 96 65 FA BD 0A E1 A3 03
DataArrived >>
DataArrived >> flag = 00 5C 41 99
DataArrived >>
DataArrived >> flag = 00 17 17 D9
DataArrived >> TEA 加密, 内容=76 E4 B8 DD 76 E4 B8 DD 00 05 94 B3 0A 3C 90 09
DataArrived >> paccket sent: 02 37 13 00 17 17 D9 76 E4 B8 DD 02 00 00 00 01 01 01 00 00 68 20 9C C7 E6 3C D1 AF 26 12 08 54 44 FC 3B 2B 66 EC 2E 34 81 F4 82 F5 C6 0E 88 DC 23 C5 C5 8B D3 C6 03
DataArrived >> AnalyMessage
*
*/
else -> throw IllegalStateException()
}
}
}
override fun toString(): String {
return this.javaClass.simpleName + this.getAllDeclaredFields().joinToString(", ", "{", "}") { it.trySetAccessible(); it.name + "=" + it.get(this) }
}
}

View File

@ -18,7 +18,7 @@ class ServerLoginResponseResendPacket(input: DataInputStream, val flag: Flag) :
}
lateinit var _0836_tlv0006_encr: ByteArray;
lateinit var token: ByteArray
var token00BA: ByteArray? = null
lateinit var tgtgtKey: ByteArray
override fun decode() {
@ -29,7 +29,7 @@ class ServerLoginResponseResendPacket(input: DataInputStream, val flag: Flag) :
when (flag) {
Flag.`08 36 31 03` -> {
token = this.input.goto(153).readNBytes(56)
token00BA = this.input.goto(153).readNBytes(56)
}
Flag.OTHER -> {

View File

@ -1,7 +1,10 @@
package net.mamoe.mirai.network.packet.server.login
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.server.*
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.util.TEACryptor
import net.mamoe.mirai.util.hexToBytes
import net.mamoe.mirai.util.toHexString
@ -39,11 +42,11 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream, val packetDataLen
//??
var b = this.input.readNBytes(2)
val msgLength = when (b.toUByteArray().toHexString()) {
"01 07" -> 0
"00 33" -> 28
"01 10" -> 65
else -> throw IllegalStateException()
}//144
"01 07" -> 0
"00 33" -> 28
"01 10" -> 65
else -> throw IllegalStateException()
}//144
System.out.println(msgLength)
@ -96,16 +99,16 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream, val packetDataLen
this.token38 = this.input.readNBytes(56)//82
this.input.skip(60L)//142
val msgLength = when (this.input.readNBytes(2).toUByteArray().toHexString()) {
val msgLength = when (val id = this.input.readNBytes(2).toUByteArray().toHexString()) {
"01 07" -> 0
"00 33" -> 28
"01 10" -> 64
else -> throw IllegalStateException()
else -> throw IllegalStateException(id)
}
this._0828_rec_decr_key = this.input.readNBytes(171 + msgLength,16)
this._0828_rec_decr_key = this.input.readNBytes(171 + msgLength, 16)
this.token88 = this.input.readNBytes(189 + msgLength,136)
this.token88 = this.input.readNBytes(189 + msgLength, 136)
val nickLength = this.input.goto(624 + msgLength).readByte().toInt()
this.nick = this.input.readVarString(nickLength)
@ -123,8 +126,12 @@ class ServerLoginResponseSuccessPacketEncrypted(input: DataInputStream, val leng
@ExperimentalUnsignedTypes
fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseSuccessPacket {//todo test
this.input.skip(7)
return ServerLoginResponseSuccessPacket(TEACryptor.decrypt(TEACryptor.decrypt(this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }, Protocol.shareKey.hexToBytes()), tgtgtKey).dataInputStream(), length);
input.skip(7)
var bytes = input.readAllBytes();
bytes = bytes.copyOfRange(0, bytes.size - 1);
println(bytes.toUByteArray().toHexString())
return ServerLoginResponseSuccessPacket(DataInputStream(TEACryptor.decrypt(bytes, Protocol.shareKey.hexToBytes()).inputStream()), length);
//TeaDecrypt(取文本中间(data, 43, 取文本长度(data) 45), m_0828_rec_decr_key)
}
}

View File

@ -1,6 +1,5 @@
package net.mamoe.mirai.network.packet.server.touch
import lombok.ToString
import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.readIP
@ -18,13 +17,12 @@ import java.io.DataInputStream
*
* @author Him188moe
*/
@ToString
class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) {
var serverIP: String? = null;
var loginTime: Int = 0
lateinit var loginIP: String
lateinit var token: ByteArray
lateinit var token0825: ByteArray
lateinit var tgtgtKey: ByteArray
enum class Type {
@ -41,7 +39,7 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp
}
0x00 -> {
input.skip(4)
token = input.readNBytes(56)
token0825 = input.readNBytes(56)
input.skip(6)
loginTime = input.readInt()

View File

@ -239,6 +239,7 @@ public class TEACryptor {
}
public byte[] encrypt(byte[] plaintext) {
System.out.println("TEA加密, 原文=" + UtilsKt.toUHexString(plaintext));
return encrypt(plaintext, 0, plaintext.length);
}

View File

@ -3,6 +3,7 @@ package net.mamoe.mirai.util
import net.mamoe.mirai.network.Protocol
import java.io.ByteArrayOutputStream
import java.io.DataOutputStream
import java.lang.reflect.Field
import java.util.*
import java.util.zip.CRC32
@ -28,33 +29,80 @@ object Utils {
}
}
fun ByteArray.toHexString(): String = toHexString(" ")
fun ByteArray.toHexString(separator: String = " "): String = Utils.toHexString(this, separator)
@ExperimentalUnsignedTypes
fun ByteArray.toUHexString(separator: String = " "): String = this.toUByteArray().toHexString(separator)
@ExperimentalUnsignedTypes
fun ByteArray.toUHexString(): String = this.toUByteArray().toHexString()
@ExperimentalUnsignedTypes
fun UByteArray.toHexString(separator: String = " "): String = Utils.toHexString(this, separator)
@ExperimentalUnsignedTypes
fun Byte.toHexString(): String = this.toUByte().toString(16)
fun UByteArray.toHexString(): String = toHexString(" ")
@ExperimentalUnsignedTypes
fun Byte.toHexString(): String = this.toUByte().toString(16)
@ExperimentalUnsignedTypes
fun String.hexToBytes(): ByteArray = Protocol.hexToBytes(this)
@ExperimentalUnsignedTypes
fun String.hexToUBytes(): UByteArray = Protocol.hexToUBytes(this)
@ExperimentalUnsignedTypes//todo test that
@ExperimentalUnsignedTypes
fun String.hexToShort(): Short = hexToBytes().let { ((it[1].toInt() shl 8) + it[0]).toShort() }
@ExperimentalUnsignedTypes
fun String.hexToByte(): Byte = hexToBytes()[0]
open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream()) {
open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray()
@ExperimentalUnsignedTypes
open fun toUByteArray(): UByteArray = (out as ByteArrayOutputStream).toByteArray().toUByteArray();
}
fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDataOutputStream().let { t(it); return it.toByteArray() }
@ExperimentalUnsignedTypes
fun getRandomKey(length: Int): ByteArray {
val bytes = LinkedList<Byte>();
for (i in 0..length) bytes.add((Math.random() * 255).toByte())
repeat(length) { bytes.add((Math.random() * 255).toByte()) }
return bytes.toByteArray();
}
fun getCrc32(key: ByteArray): Long = with(CRC32()) { update(key); return@with this.value };
fun getCrc32(key: ByteArray): Int = CRC32().let { it.update(key); it.value.toInt() }
/**
* 获取类的所有字段(类成员变量), 包括父类的和私有的. <br></br>
* 相当于将这个类和它所有父类的 [Class.getDeclaredFields] 都合并成一个 [List] <br></br>
* 不会排除重名的字段. <br></br>
*
* @param clazz class
*
* @return field list
*/
@Throws(SecurityException::class)
fun Any.getAllDeclaredFields(): List<Field> {
var clazz: Class<*> = this.javaClass;
val list = LinkedList<Field>()
loop@ do {
if (!clazz.name.contains("net.mamoe")) {
break@loop
}
list.addAll(clazz.declaredFields.filter { (it.name == "Companion" || it.name == "input").not() }.toList())
if (clazz.superclass == null) {
break
}
clazz = clazz.superclass
} while (clazz != Object::javaClass)
return list
}

View File

@ -1,78 +0,0 @@
/**
* @author NaturalHG
* This could be used to check packet encoding..
* but better to run under UNIX
*/
public class HaxComparator {
/**
* a string result
*/
private static String RED = "\033[31m";
private static String GREEN = "\033[33m";
public static String compare(String hax1s, String hax2s){
StringBuilder builder = new StringBuilder();
String[] hax1 = hax1s.trim().split(" ");
String[] hax2 = hax2s.trim().split(" ");
if(hax1.length == hax2.length){
builder.append(GREEN).append("长度一致:").append(hax1.length);
}else{
builder.append(RED).append("长度不一致").append(hax1.length).append("/").append(hax2.length);
}
StringBuilder hax1b = new StringBuilder();
StringBuilder hax2b = new StringBuilder();
int dif = 0;
for (int i=0;i<Math.max(hax1.length,hax2.length);++i){
String h1 = null;
String h2 = null;
boolean isDif = false;
if(hax1.length <= i){
h1 = RED + "__";
isDif = true;
}
if(hax2.length <= i){
h2 = RED + "__";
isDif = true;
}
if(h1 == null && h2 == null){
h1 = hax1[i];
h2 = hax2[i];
if(h1.equals(h2)){
h1 = GREEN + h1;
h2 = GREEN + h2;
}else{
h1 = RED + h1;
h2 = RED + h2;
isDif = true;
}
}else{
if(h1 == null){
h1 = RED + hax1[i];
}
if(h2 == null){
h2 = RED + hax2[i];
}
}
hax1b.append(h1).append(" ");
hax2b.append(h2).append(" ");
if(isDif){
++dif;
}
}
return (builder.append(" ").append(dif).append(" 个不同").append("\n").append(hax1b).append("\n").append(hax2b)).toString();
}
public static void main(String[] args){
System.out.println(HaxComparator.compare("00 01 09 00 70 00 01 23 7B FE 83 D1 37 64 46 84 9D E9 9C E7 BB 8E 44 00 38 9B A4 3B C2 BB 49 4C DA B0 A5 5C C8 27 29 74 EF CB 38 59 4E 03 C8 15 C6 F9 BF 3F 88 22 7E 22 5B 48 02 71 59 1A 2C C8 42 BA 81 76 66 0C 46 91 89 6C B2 17 BF 2A 00 F8 8B 00 20 7C 28 07 3D AA 24 EF B4 49 9D 85 7F 4C F5 41 56 F4 1F AD 53 81 9F C1 03 F3 03 65 DD 0C 04 CC 68 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","AA CC AA DD EE GG HH"));
}
}

View File

@ -0,0 +1,189 @@
import kotlin.ranges.IntRange;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import net.mamoe.mirai.network.Protocol;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* This could be used to check packet encoding..
* but better to run under UNIX
*
* @author NaturalHG
*/
public class HexComparator {
/**
* a string result
*/
private static final String RED = "\033[31m";
private static final String GREEN = "\033[33m";
private static final String UNKNOWN = "\033[30m";
private static final String BLUE = "\033[34m";
private static class ConstMatcher {
private static final List<Field> CONST_FIELDS = new LinkedList<>() {{
List.of(Protocol.class).forEach(aClass -> Arrays.stream(aClass.getDeclaredFields()).peek(this::add).forEach(Field::trySetAccessible));
}};
private final List<Match> matches = new LinkedList<>();
private ConstMatcher(String hex) {
CONST_FIELDS.forEach(field -> {
for (IntRange match : match(hex, field)) {
matches.add(new Match(match, field.getName()));
}
});
}
private String getMatchedConstName(int hexNumber) {
for (Match match : this.matches) {
if (match.range.contains(hexNumber)) {
return match.constName;
}
}
return null;
}
private static List<IntRange> match(String hex, Field field) {
final String constValue;
try {
constValue = ((String) field.get(null)).trim();
if (constValue.length() / 3 <= 3) {//Minimum numbers of const hex bytes
return new LinkedList<>();
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (ClassCastException ignored) {
return new LinkedList<>();
}
return new LinkedList<>() {{
int index = 0;
while ((index = hex.indexOf(constValue, index + 1)) != -1) {
add(new IntRange(index / 3, (index + constValue.length()) / 3));
}
}};
}
@ToString
@Getter
@AllArgsConstructor
private static class Match {
private IntRange range;
private String constName;
}
}
private static String compare(String hex1s, String hex2s) {
StringBuilder builder = new StringBuilder();
String[] hex1 = hex1s.trim().replace("\n", "").split(" ");
String[] hex2 = hex2s.trim().replace("\n", "").split(" ");
ConstMatcher constMatcher1 = new ConstMatcher(hex1s);
ConstMatcher constMatcher2 = new ConstMatcher(hex2s);
if (hex1.length == hex2.length) {
builder.append(GREEN).append("长度一致:").append(hex1.length);
} else {
builder.append(RED).append("长度不一致").append(hex1.length).append("/").append(hex2.length);
}
StringBuilder numberLine = new StringBuilder();
StringBuilder hex1b = new StringBuilder();
StringBuilder hex2b = new StringBuilder();
int dif = 0;
for (int i = 0; i < Math.max(hex1.length, hex2.length); ++i) {
String h1 = null;
String h2 = null;
boolean isDif = false;
if (hex1.length <= i) {
h1 = RED + "__";
isDif = true;
} else {
String matchedConstName = constMatcher1.getMatchedConstName(i);
if (matchedConstName != null) {
h1 = BLUE + hex1[i];
}
}
if (hex2.length <= i) {
h2 = RED + "__";
isDif = true;
} else {
String matchedConstName = constMatcher2.getMatchedConstName(i);
if (matchedConstName != null) {
h2 = BLUE + hex2[i];
}
}
if (h1 == null && h2 == null) {
h1 = hex1[i];
h2 = hex2[i];
if (h1.equals(h2)) {
h1 = GREEN + h1;
h2 = GREEN + h2;
} else {
h1 = RED + h1;
h2 = RED + h2;
isDif = true;
}
} else {
if (h1 == null) {
h1 = RED + hex1[i];
}
if (h2 == null) {
h2 = RED + hex2[i];
}
}
numberLine.append(UNKNOWN).append(getNumber(i)).append(" ");
hex1b.append(" ").append(h1).append(" ");
hex2b.append(" ").append(h2).append(" ");
if (isDif) {
++dif;
}
}
return (builder.append(" ").append(dif).append(" 个不同").append("\n")
.append(numberLine).append("\n")
.append(hex1b).append("\n")
.append(hex2b))
.toString();
}
private static String getNumber(int number) {
if (number < 10) {
return "00" + number;
}
if (number < 100) {
return "0" + number;
}
return String.valueOf(number);
}
public static void main(String[] args) {
System.out.println(HexComparator.compare(
//mirai
"01 12 00 38 D7 B4 57 68 68 BA 91 9D 2C 6F F0 B8 1A 77 4A DC 10 FE 74 E6 03 CE EA 90 5A 43 FD 19 21 94 EF 41 C3 2B 48 B7 91 70 DD AE 47 EA C7 EC 69 5A 6D 16 3B CA E8 DC 82 81 24 74 03 0F 00 11 00 0F 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55 00 05 00 06 00 02 76 E4 B8 DD 00 06 00 78 78 F4 FC F9 F2 B0 04 32 4A 01 F7 0B 23 7A 5E 30 E9 42 83 89 C4 D2 7A F7 7D 6E 71 FF FC 97 81 3A FC 11 75 3B D6 7C E8 C2 04 3E CD B1 34 57 C3 B4 AF 40 87 BD 06 18 7F 7B E8 8E F5 42 0F A8 A8 87 44 3A A5 51 69 61 F1 12 F4 94 DE BA 37 D9 50 5C 03 ED CB DE 6E 68 B4 DE 79 6E BF A9 07 D2 E5 56 7A AF 35 12 00 0C 4D 9D F4 E5 0C 36 9C 5C 5A CE F7 2D 95 28 82 8A FC E5 00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B 00 1A 00 40 56 5C 1A 38 F9 6A 88 F8 34 EF 68 FC 83 9D 61 9B 7A 07 F6 37 CD 1E C4 9A C9 B2 81 B3 F5 67 C4 74 63 23 30 64 E8 32 6F BD 35 14 0D 75 2D DF 0F 38 80 D3 3C 11 0D 1B 74 EF C8 6D 54 42 E7 DB 94 B9 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 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 10 00 3C 00 01 00 38 E0 65 0C 69 9A EE D9 90 CE 5D AF 23 6B 49 03 0D 98 47 25 3F B5 BD 88 BB 54 50 72 E0 37 8E 66 ED A6 37 18 77 71 5D 66 A6 A3 CD A5 BC 9B CD 87 42 DB 41 59 3E 54 A7 90 DC 03 12 00 05 01 00 00 00 01 05 08 00 05 10 00 00 00 00 03 13 00 19 01 01 02 00 10 04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA 00 00 00 00 01 02 00 62 00 01 04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48 00 38 E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3 00 14 32 8C B5 CB 10 2E 0A 31 F2 EB 6D FC 13 CB 14 83 31 CD 75 C6"
,
//e
"01 12 00 38 D5 CC FC 5E BF 39 4C 07 7F FF AE 3C C2 10 E0 0E 3D C1 7B 6C 1C 58 9C 97 AB DE DC 4C B7 8E AB DA 77 BE 5F AD 8D 3C EA 7D B8 3D 5E B3 5B 6B DD 32 E6 A5 0C 6F B7 93 E4 C3 03 0F 00 11 00 0F 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55 00 05 00 06 00 02 76 E4 B8 DD 00 06 00 78 64 5C 48 D5 BF 98 6A 81 8F B5 09 DA A5 83 0E 45 BB 99 9B 03 42 2A 87 95 48 88 52 0D 5F 0B C1 4D A7 5F BF 60 4F 3D A1 04 D3 B4 E4 D2 45 71 5C 74 95 80 86 45 E0 26 EA B2 B1 09 0B 56 22 68 7C 5D 8D 9E 69 E4 C5 4E 0C EA F5 6F 90 FF 4B 43 43 EB 4F 76 45 70 DA 12 C7 1E A5 14 B8 5B 78 79 75 5E 2C F3 5D 1A C4 39 D5 AE 1A 70 EC AF A1 F5 FF D6 D3 B9 C6 DA 71 7E 15 52 00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B 00 1A 00 40 9D AB 45 74 6A E5 3F E2 8E 81 16 6C BB FA 0D A1 37 28 2F B9 02 3D EB 07 C7 ED 95 99 F9 35 27 35 58 67 4A FA 6E E4 89 37 8A 00 3B 19 C5 15 7E F6 83 D5 CF 66 9C FD 10 9F 27 90 31 3B 2E 98 F9 4C 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 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 10 00 3C 00 01 00 38 3A 51 49 BC 3C 44 78 A1 A7 6D B7 98 03 05 9F 42 E1 15 E5 53 0C C1 03 82 5E AE AD FC 44 C6 E9 85 66 51 F2 E2 67 B4 60 DC 89 EC E4 56 13 52 E6 AA C4 5A D1 FA 3D E7 10 92 03 12 00 05 01 00 00 00 01 05 08 00 05 01 00 00 00 00 03 13 00 19 01 01 02 00 10 04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA 00 00 00 00 01 02 00 62 00 01 04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48 00 38 E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3 00 14 D5 4E 31 3E 5E B3 28 6C 94 FB 25 CA E8 C4 A4 28 09 02 B2 58"
));
System.out.println(HexComparator.compare(
//e
"90 5E 39 DF 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 55 35 05 8E C9 BA 16 D0 01 63 5B 59 4B 59 52 31 01 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 7B 7B 7B 7B 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B AA BB CC DD EE FF AA BB CC",
//mirai
"6F 0B DF 92 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 55 35 05 8E C9 BA 16 D0 01 63 5B 59 4B 59 52 31 01 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 E9 E9 E9 E9 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B AA BB CC DD EE FF AA BB CC\n\n\n"
));
}
}

20
pom.xml
View File

@ -63,12 +63,6 @@
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.intellij</groupId>
@ -94,13 +88,6 @@
<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.mina/mina-core -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.1.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
<groupId>net.java.dev.jna</groupId>
@ -114,6 +101,13 @@
<version>2.8.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core -->
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>1.3.0-M2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>