mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-19 10:59:14 +08:00
update
This commit is contained in:
parent
2ff1e9bf9e
commit
88d2fa0449
@ -97,7 +97,7 @@ public class MiraiServer {
|
||||
|
||||
Robot robot = new Robot(1994701021L);
|
||||
try {
|
||||
robot.connect(Protocol.SERVER_IP.get(2), 8000);
|
||||
robot.connect(Protocol.Companion.getSERVER_IP().get(2), 8000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
|
@ -1,61 +1,62 @@
|
||||
package net.mamoe.mirai.network;
|
||||
package net.mamoe.mirai.network
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.net.InetAddress
|
||||
import java.util.*
|
||||
import java.util.stream.Collectors
|
||||
|
||||
/**
|
||||
* @author Him188moe @ Mirai Project
|
||||
*/
|
||||
public interface Protocol {
|
||||
List<String> SERVER_IP = new ArrayList<>() {{
|
||||
add("183.60.56.29");
|
||||
interface Protocol {
|
||||
companion object {
|
||||
val SERVER_IP: ArrayList<String> = object : ArrayList<String>() {
|
||||
init {
|
||||
add("183.60.56.29")
|
||||
|
||||
List.of(
|
||||
"sz2.tencent.com",
|
||||
"sz3.tencent.com",
|
||||
"sz4.tencent.com",
|
||||
"sz5.tencent.com",
|
||||
"sz6.tencent.com",
|
||||
"sz8.tencent.com",
|
||||
"sz9.tencent.com"
|
||||
).forEach(s -> {
|
||||
try {
|
||||
SERVER_IP.add(InetAddress.getByName(s).getHostAddress());
|
||||
} catch (UnknownHostException ignored) {
|
||||
arrayOf(
|
||||
"sz2.tencent.com",
|
||||
"sz3.tencent.com",
|
||||
"sz4.tencent.com",
|
||||
"sz5.tencent.com",
|
||||
"sz6.tencent.com",
|
||||
"sz8.tencent.com",
|
||||
"sz9.tencent.com"
|
||||
).forEach { this.add(InetAddress.getByName(it).hostAddress) }
|
||||
}
|
||||
});
|
||||
}};
|
||||
|
||||
|
||||
String head = "02";
|
||||
String ver = "37 13 ";
|
||||
String fixVer = "03 00 00 00 01 2E 01 00 00 68 52 00 00 00 00 ";
|
||||
String tail = " 03";
|
||||
String _fixVer = "02 00 00 00 01 01 01 00 00 68 20 ";
|
||||
String _0825data0 = "00 18 00 16 00 01 ";
|
||||
String _0825data2 = "00 00 04 53 00 00 00 01 00 00 15 85 ";
|
||||
String _0825key = "A4 F1 91 88 C9 82 14 99 0C 9E 56 55 91 23 C8 3D";
|
||||
String redirectionKey = "A8 F2 14 5F 58 12 60 AF 07 63 97 D6 76 B2 1A 3B";
|
||||
String publicKey = "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";
|
||||
String shareKey = "1A E9 7F 7D C9 73 75 98 AC 02 E0 80 5F A9 C6 AF";
|
||||
String _0836fix = "06 A9 12 97 B7 F8 76 25 AF AF D3 EA B4 C8 BC E7 ";
|
||||
|
||||
String _00BaKey = "C1 9C B8 C8 7B 8C 81 BA 9E 9E 7A 89 E1 7A EC 94";
|
||||
String _00BaFixKey = "69 20 D1 14 74 F5 B3 93 E4 D5 02 B3 71 1A CD 2A";
|
||||
|
||||
String encryptKey = "“BA 42 FF 01 CF B4 FF D2 12 F0 6E A7 1B 7C B3 08”";
|
||||
|
||||
|
||||
static byte[] hexToBytes(String hex) {
|
||||
var list = Arrays.stream(hex.split(" ")).map(String::trim).map(s -> Byte.valueOf(s, 16)).collect(Collectors.toList());
|
||||
var buff = new byte[list.size()];
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
buff[i] = list.get(i);
|
||||
}
|
||||
return buff;
|
||||
|
||||
|
||||
const val head = "02"
|
||||
const val ver = "37 13 "
|
||||
const val fixVer = "03 00 00 00 01 2E 01 00 00 68 52 00 00 00 00 "
|
||||
const val tail = " 03"
|
||||
const val _fixVer = "02 00 00 00 01 01 01 00 00 68 20 "
|
||||
const val _0825data0 = "00 18 00 16 00 01 "
|
||||
const val _0825data2 = "00 00 04 53 00 00 00 01 00 00 15 85 "
|
||||
const val _0825key = "A4 F1 91 88 C9 82 14 99 0C 9E 56 55 91 23 C8 3D"
|
||||
const val redirectionKey = "A8 F2 14 5F 58 12 60 AF 07 63 97 D6 76 B2 1A 3B"
|
||||
const val publicKey = "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"
|
||||
const val shareKey = "1A E9 7F 7D C9 73 75 98 AC 02 E0 80 5F A9 C6 AF"
|
||||
const val _0836fix = "06 A9 12 97 B7 F8 76 25 AF AF D3 EA B4 C8 BC E7 "
|
||||
|
||||
const val _00BaKey = "C1 9C B8 C8 7B 8C 81 BA 9E 9E 7A 89 E1 7A EC 94"
|
||||
const val _00BaFixKey = "69 20 D1 14 74 F5 B3 93 E4 D5 02 B3 71 1A CD 2A"
|
||||
|
||||
const val encryptKey = "“BA 42 FF 01 CF B4 FF D2 12 F0 6E A7 1B 7C B3 08”"
|
||||
|
||||
|
||||
fun hexToBytes(hex: String): ByteArray = Arrays
|
||||
.stream(hex.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
|
||||
.map { value -> value.trim { it <= ' ' } }
|
||||
.map { s -> s.toInt(16).toByte() }
|
||||
.collect(Collectors.toList()).toByteArray()
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun hexToUBytes(hex: String): UByteArray = Arrays
|
||||
.stream(hex.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
|
||||
.map { value -> value.trim { it <= ' ' } }
|
||||
.map { s -> s.toInt(16).toByte() }
|
||||
.collect(Collectors.toList()).toByteArray().toUByteArray()
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
package net.mamoe.mirai.network.packet.client;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.mamoe.mirai.network.Protocol;
|
||||
import net.mamoe.mirai.network.packet.PacketId;
|
||||
import net.mamoe.mirai.util.TEAEncryption;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Him188moe @ Mirai Project
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@PacketId(0x00_58)
|
||||
public class ClientHeartbeatPacket extends ClientPacket {
|
||||
public long qq;
|
||||
public byte[] sessionKey;//登录后获得
|
||||
|
||||
@Override
|
||||
public void encode() throws IOException {
|
||||
this.writeRandom(2);
|
||||
this.writeQQ(qq);
|
||||
this.writeHex(Protocol.fixVer);
|
||||
this.write(TEAEncryption.encrypt(new byte[]{0x00, 0x01, 0x00, 0x01}, sessionKey));
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package net.mamoe.mirai.network.packet.client
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
import net.mamoe.mirai.network.packet.PacketId
|
||||
import net.mamoe.mirai.util.TEAEncryption
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* @author Him188moe @ Mirai Project
|
||||
*/
|
||||
@PacketId(value = 0x00_58)
|
||||
class ClientHeartbeatPacket : ClientPacket() {
|
||||
var qq: Long = 0
|
||||
var sessionKey: ByteArray? = null//登录后获得
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun encode() {
|
||||
this.writeRandom(2)
|
||||
this.writeQQ(qq)
|
||||
this.writeHex(Protocol.fixVer)
|
||||
this.write(TEAEncryption.encrypt(byteArrayOf(0x00, 0x01, 0x00, 0x01), sessionKey))
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package net.mamoe.mirai.network.packet.client;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.mamoe.mirai.network.Protocol;
|
||||
import net.mamoe.mirai.network.packet.PacketId;
|
||||
import net.mamoe.mirai.util.TEAEncryption;
|
||||
import net.mamoe.mirai.util.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Him188moe @ Mirai Project
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@PacketId(0x08_25_31_01)
|
||||
public class ClientLoginPacket extends ClientPacket {
|
||||
public long qq;
|
||||
|
||||
@Override
|
||||
public void encode() throws IOException {
|
||||
this.writeQQ(qq);
|
||||
this.writeHex(Protocol.fixVer);
|
||||
this.writeHex(Protocol._0825key);
|
||||
|
||||
|
||||
//TEA 加密
|
||||
this.write(TEAEncryption.encrypt(new ClientPacket() {
|
||||
@Override
|
||||
public void encode() throws IOException {
|
||||
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(Protocol.SERVER_IP.get(2));
|
||||
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);
|
||||
}
|
||||
}.encodeToByteArray(), Protocol.hexToBytes(Protocol._0825key)));
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
try {
|
||||
var pk = new ClientLoginPacket();
|
||||
pk.qq = 1994701021;
|
||||
pk.encode();
|
||||
pk.writeHex(Protocol.tail);
|
||||
System.out.println("pk.toByteArray() = " + Arrays.toString(pk.toByteArray()));
|
||||
System.out.println(Utils.INSTANCE.toHexString(pk.toByteArray()));
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package net.mamoe.mirai.network.packet.client
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
import net.mamoe.mirai.network.packet.PacketId
|
||||
import net.mamoe.mirai.util.ByteArrayDataOutputStream
|
||||
import net.mamoe.mirai.util.TEAEncryption
|
||||
import net.mamoe.mirai.util.toHexString
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* @author Him188moe @ Mirai Project
|
||||
*/
|
||||
@PacketId(0x08_25_31_01)
|
||||
class ClientLoginPacket : ClientPacket() {
|
||||
var qq: Long = 0
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun encode() {
|
||||
this.writeQQ(qq)
|
||||
this.writeHex(Protocol.fixVer)
|
||||
this.writeHex(Protocol._0825key)
|
||||
|
||||
|
||||
//TEA 加密
|
||||
this.write(TEAEncryption.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(Protocol.SERVER_IP.get(2));
|
||||
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)
|
||||
return super.toByteArray()
|
||||
}
|
||||
}.toByteArray(), Protocol.hexToBytes(Protocol._0825key)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun main() {
|
||||
val pk = ClientLoginPacket()
|
||||
pk.qq = 1994701021
|
||||
pk.encode()
|
||||
pk.writeHex(Protocol.tail)
|
||||
println("pk.toByteArray() = " + pk.toUByteArray().contentToString())
|
||||
println(pk.toUByteArray().toHexString(" "))
|
||||
}
|
||||
|
||||
|
||||
//mirai: 02 37 13 08 25 31 01 00 00 00 00 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 94 06 D9 3B 40 B5 E2 39 58 F5 E1 71 46 63 FF 6C CE 1E F1 BF CB F5 04 67 96 81 01 7C EF 47 10 15 45 8A 59 F7 B4 39 48 A3 E1 9C 74 3C DC 8E 7E 2F CF B6 C1 0C 2C C6 D6 7F DC 98 12 9C 88 35 29 33 C6 98 A9 81 C7 7B 2D 76 00 67 A1 DD 82 1E 12 04 DF DF 48 18 E0 C3 C8 54 B5 C2 16 A8 C4 CD BD 7D FD 5E 2A A9 74 68 82 44 F7 0D 7D 0E 6C 4F C8 05 03
|
||||
//epl : 02 37 13 08 25 31 02 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 D9 9E E9 58 5A E5 46 0D 40 D0 A5 A2 DF 48 8D 23 FB 25 C1 1A 4B D1 27 BA AB B2 69 AB DE 91 C0 63 65 2B 3A 0F 06 0C 3F EC 5C 48 A7 AE 25 06 3F 3C 7A A2 46 91 22 8E B2 A0 41 3F 5D C8 A5 C6 64 64 62 11 A1 9E 14 51 28 39 41 01 07 B5 8B 98 33 AB 50 AD 2F 05 8E F1 17 D7 1D 67 61 1B CD E9 B8 C6 A5 A7 F9 48 F7 BE 05 BC 03
|
@ -1,81 +1,83 @@
|
||||
package net.mamoe.mirai.network.packet.client;
|
||||
package net.mamoe.mirai.network.packet.client
|
||||
|
||||
import lombok.Getter;
|
||||
import net.mamoe.mirai.network.Protocol;
|
||||
import net.mamoe.mirai.network.packet.Packet;
|
||||
import net.mamoe.mirai.network.packet.PacketId;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
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.ByteArrayDataOutputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* @author Him188moe @ Mirai Project
|
||||
*/
|
||||
public abstract class ClientPacket extends DataOutputStream implements Packet {
|
||||
|
||||
abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
|
||||
@Getter
|
||||
private final int packageId;
|
||||
val packageId: Int
|
||||
|
||||
public ClientPacket() {
|
||||
super(new ByteArrayOutputStream());
|
||||
var annotation = this.getClass().getAnnotation(PacketId.class);
|
||||
packageId = annotation.value();
|
||||
init {
|
||||
val annotation = this.javaClass.getAnnotation(PacketId::class.java)
|
||||
packageId = annotation.value
|
||||
|
||||
try {
|
||||
this.writeHex(Protocol.head);
|
||||
this.writeHex(Protocol.ver);
|
||||
writePacketId();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
this.writeHex(Protocol.head)
|
||||
this.writeHex(Protocol.ver)
|
||||
writePacketId()
|
||||
} catch (e: IOException) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void writeIp(String ip) throws IOException {
|
||||
for (String s : ip.split("\\.")) {
|
||||
this.writeInt(Integer.parseInt(s));
|
||||
}
|
||||
@Throws(IOException::class)
|
||||
fun writePacketId() {
|
||||
this.writeInt(this@ClientPacket.packageId)
|
||||
}
|
||||
|
||||
protected void writePacketId() throws IOException {
|
||||
this.writeInt(this.packageId);
|
||||
}
|
||||
|
||||
protected void writeHex(String hex) throws IOException {
|
||||
for (String s : hex.split(" ")) {
|
||||
s = s.trim();
|
||||
if (s.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
this.writeByte(Byte.valueOf(s, 16));
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeRandom(int length) throws IOException {
|
||||
for (int i = 0; i < length; i++) {
|
||||
this.writeByte((byte) (int) (Math.random() * 255));
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeQQ(long qq) throws IOException {
|
||||
this.writeLong(qq);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encode this packet.
|
||||
* <p>
|
||||
* Before sending the packet, an {@linkplain Protocol#tail tail} will be added.
|
||||
*
|
||||
*
|
||||
* Before sending the packet, an [tail][Protocol.tail] will be added.
|
||||
*/// TODO: 2019/8/9 添加 tail
|
||||
public abstract void encode() throws IOException;
|
||||
@Throws(IOException::class)
|
||||
abstract fun encode()
|
||||
|
||||
public byte[] toByteArray() {
|
||||
return ((ByteArrayOutputStream) this.out).toByteArray();
|
||||
}
|
||||
|
||||
public final byte[] encodeToByteArray() throws IOException {
|
||||
encode();
|
||||
return toByteArray();
|
||||
@Throws(IOException::class)
|
||||
fun encodeToByteArray(): ByteArray {
|
||||
encode()
|
||||
return toByteArray()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeIp(ip: String) {
|
||||
for (s in ip.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
|
||||
this.writeInt(Integer.parseInt(s))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeHex(hex: String) {
|
||||
for (s in hex.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
|
||||
if (s.isEmpty()) {
|
||||
continue
|
||||
}
|
||||
this.writeByte(Integer.parseInt(s, 16))
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeRandom(length: Int) {
|
||||
for (i in 0 until length) {
|
||||
this.writeByte((Math.random() * 255).toInt().toByte().toInt())
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun DataOutputStream.writeQQ(qq: Long) {
|
||||
this.writeLong(qq)
|
||||
}
|
@ -1,16 +1,43 @@
|
||||
package net.mamoe.mirai.util
|
||||
|
||||
import net.mamoe.mirai.network.Protocol
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.DataOutputStream
|
||||
|
||||
/**
|
||||
* @author Him188moe @ Mirai Project
|
||||
*/
|
||||
object Utils {
|
||||
fun toHexString(byteArray: ByteArray): String = byteArray.joinToString(" ") { it.toString(16) }
|
||||
fun toHexString(byteArray: ByteArray, separator: String = ","): String = byteArray.joinToString(separator) {
|
||||
var ret = it.toString(16).toUpperCase();
|
||||
if (ret.length == 1) {
|
||||
ret = "0$ret";
|
||||
}
|
||||
return@joinToString ret;
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun toHexString(byteArray: UByteArray, separator: String = ","): String = byteArray.joinToString(separator) {
|
||||
var ret = it.toString(16).toUpperCase();
|
||||
if (ret.length == 1) {
|
||||
ret = "0$ret";
|
||||
}
|
||||
return@joinToString ret;
|
||||
}
|
||||
}
|
||||
|
||||
fun ByteArray.toHexString(): String = Utils.toHexString(this)
|
||||
fun ByteArray.toHexString(separator: String = ", "): String = Utils.toHexString(this, separator)
|
||||
@ExperimentalUnsignedTypes
|
||||
fun UByteArray.toHexString(separator: String = ", "): String = Utils.toHexString(this, separator)
|
||||
|
||||
fun Byte.toHexString(): String = this.toString(16)
|
||||
|
||||
fun String.hexToBytes(): ByteArray = Protocol.hexToBytes(this)
|
||||
fun String.hexToBytes(): ByteArray = Protocol.hexToBytes(this)
|
||||
@ExperimentalUnsignedTypes
|
||||
fun String.hexToUBytes(): UByteArray = Protocol.hexToUBytes(this)
|
||||
|
||||
open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream()) {
|
||||
open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray()
|
||||
@ExperimentalUnsignedTypes
|
||||
open fun toUByteArray(): UByteArray = (out as ByteArrayOutputStream).toByteArray().toUByteArray();
|
||||
}
|
Loading…
Reference in New Issue
Block a user