mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-12 18:50:20 +08:00
update
This commit is contained in:
parent
6673bada67
commit
97b90b08c8
@ -5,7 +5,7 @@ package net.mamoe.mirai.contact
|
|||||||
*
|
*
|
||||||
* @author Him188moe @ Mirai Project
|
* @author Him188moe @ Mirai Project
|
||||||
*/
|
*/
|
||||||
abstract class Contact(number: Long) {
|
abstract class Contact(val number: Long) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Async
|
* Async
|
||||||
|
@ -19,7 +19,7 @@ class QQ(number: Long) : Contact(number) {
|
|||||||
/**
|
/**
|
||||||
* At(@) this account.
|
* At(@) this account.
|
||||||
*/
|
*/
|
||||||
open fun at(): String {
|
fun at(): String {
|
||||||
return "[@" + this.number + "]"
|
return "[@$number]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
package net.mamoe.mirai.network;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Him188moe @ Mirai Project
|
|
||||||
*/
|
|
||||||
public class BinaryStream {
|
|
||||||
|
|
||||||
}
|
|
@ -11,8 +11,46 @@ import net.mamoe.mirai.network.packet.server.ServerPacket
|
|||||||
*/
|
*/
|
||||||
@Log4j2
|
@Log4j2
|
||||||
class ClientHandler(val robot: Robot) : SimpleChannelInboundHandler<ByteArray>() {
|
class ClientHandler(val robot: Robot) : SimpleChannelInboundHandler<ByteArray>() {
|
||||||
override fun channelRead0(ctx: ChannelHandlerContext?, bytes: ByteArray?) {
|
private object Reader {
|
||||||
|
private var length: Int? = null
|
||||||
|
private lateinit var bytes: ByteArray
|
||||||
|
|
||||||
|
fun init(bytes: ByteArray) {
|
||||||
|
this.length = length
|
||||||
|
this.bytes = bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads bytes, combining them to create a packet, returning remaining bytes.
|
||||||
|
*/
|
||||||
|
fun read(bytes: ByteArray): ByteArray? {
|
||||||
|
checkNotNull(this.length)
|
||||||
|
val needSize = length!! - this.bytes.size;//How many bytes we need
|
||||||
|
if (needSize == bytes.size || needSize > bytes.size) {
|
||||||
|
this.bytes += bytes
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//We got more than we need
|
||||||
|
this.bytes += bytes.copyOfRange(0, needSize)
|
||||||
|
return bytes.copyOfRange(needSize, bytes.size - needSize)//We got remaining bytes, that is of another packet
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isPacketAvailable() = this.length == this.bytes.size
|
||||||
|
|
||||||
|
fun toServerPacket(): ServerPacket {
|
||||||
|
return ServerPacket.ofByteArray(this.bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun channelRead0(ctx: ChannelHandlerContext?, bytes: ByteArray) {
|
||||||
try {
|
try {
|
||||||
|
/*val remaining = Reader.read(bytes);
|
||||||
|
if (Reader.isPacketAvailable()) {
|
||||||
|
robot.onPacketReceived(Reader.toServerPacket())
|
||||||
|
Reader.init()
|
||||||
|
remaining
|
||||||
|
}*/
|
||||||
robot.onPacketReceived(ServerPacket.ofByteArray(bytes))
|
robot.onPacketReceived(ServerPacket.ofByteArray(bytes))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
MiraiServer.getLogger().catching(e)
|
MiraiServer.getLogger().catching(e)
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package net.mamoe.mirai.network
|
package net.mamoe.mirai.network
|
||||||
|
|
||||||
import net.mamoe.mirai.network.packet.Packet
|
import net.mamoe.mirai.network.packet.Packet
|
||||||
|
import net.mamoe.mirai.network.packet.client.Client0825ResponsePacket
|
||||||
|
import net.mamoe.mirai.network.packet.server.Server0825Packet
|
||||||
import net.mamoe.mirai.network.packet.server.ServerPacket
|
import net.mamoe.mirai.network.packet.server.ServerPacket
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* [number] is a QQ number.
|
||||||
|
*
|
||||||
* @author Him188moe @ Mirai Project
|
* @author Him188moe @ Mirai Project
|
||||||
*/
|
*/
|
||||||
open class Robot() {
|
class Robot(val number: Long) {
|
||||||
|
|
||||||
internal fun onPacketReceived(packet: Packet) {
|
internal fun onPacketReceived(packet: Packet) {
|
||||||
if (packet !is ServerPacket) {
|
if (packet !is ServerPacket) {
|
||||||
@ -14,5 +18,12 @@ open class Robot() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
packet.decode()
|
packet.decode()
|
||||||
|
if (packet is Server0825Packet) {//todo 检查是否需要修改 UDP 连接???
|
||||||
|
sendPacket(Client0825ResponsePacket(packet.serverIP, number));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun sendPacket(packet: Packet) {
|
||||||
|
TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
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(0x08_25_31_02)
|
||||||
|
class Client0825ResponsePacket(private val serverIP: String, private val qq: Long) : ClientPacket() {
|
||||||
|
override fun encode() {
|
||||||
|
this.writeQQ(qq)
|
||||||
|
this.writeHex(Protocol.fixVer)
|
||||||
|
this.writeHex(Protocol.redirectionKey)
|
||||||
|
|
||||||
|
//TEA 加密
|
||||||
|
this.write(TEAEncryption.encrypt(object : ClientPacket() {
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun encode() {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}.encodeToByteArray(), Protocol.hexToBytes(Protocol.redirectionKey)))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package net.mamoe.mirai.network.packet.server
|
||||||
|
|
||||||
|
import net.mamoe.mirai.network.Protocol
|
||||||
|
import net.mamoe.mirai.util.TEAEncryption
|
||||||
|
import java.io.DataInputStream
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A packet received when logging in, used to redirect server address
|
||||||
|
*
|
||||||
|
* @author Him188moe @ Mirai Project
|
||||||
|
*/
|
||||||
|
class Server0825Packet(private val type: Type, inputStream: DataInputStream) : ServerPacket(inputStream) {
|
||||||
|
lateinit var serverIP: String;
|
||||||
|
|
||||||
|
enum class Type {
|
||||||
|
TYPE_08_25_31_01,
|
||||||
|
TYPE_08_25_31_02,
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode() {
|
||||||
|
input.skip(43 - 11)//todo: check
|
||||||
|
val data = DataInputStream(TEAEncryption.decrypt(input.readAllBytes().let { it.copyOfRange(0, it.size - 45) }, when (type) {
|
||||||
|
Type.TYPE_08_25_31_01 -> Protocol.redirectionKey.toByteArray()
|
||||||
|
Type.TYPE_08_25_31_02 -> Protocol._0825key.toByteArray()
|
||||||
|
}).inputStream());
|
||||||
|
|
||||||
|
when (data.readByte().toInt()) {
|
||||||
|
0xFE -> {
|
||||||
|
serverIP = data.readIP()
|
||||||
|
}
|
||||||
|
0X00 -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package net.mamoe.mirai.network.packet.server
|
||||||
|
|
||||||
|
import java.io.DataInputStream
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Him188moe @ Mirai Project
|
||||||
|
*/
|
||||||
|
class ServerLoginSucceedPacket(inputStream: DataInputStream) : ServerPacket(inputStream) {
|
||||||
|
override fun decode() {
|
||||||
|
}
|
||||||
|
}
|
@ -1,28 +1,55 @@
|
|||||||
package net.mamoe.mirai.network.packet.server;
|
package net.mamoe.mirai.network.packet.server
|
||||||
|
|
||||||
import net.mamoe.mirai.network.packet.Packet;
|
import net.mamoe.mirai.network.packet.Packet
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.DataInputStream
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Him188moe @ Mirai Project
|
* @author Him188moe @ Mirai Project
|
||||||
*/
|
*/
|
||||||
public abstract class ServerPacket extends DataInputStream implements Packet {
|
abstract class ServerPacket(val input: DataInputStream) : Packet {
|
||||||
public static ServerPacket ofByteArray(byte[] bytes) {
|
|
||||||
// TODO: 2019/8/15 process bytes
|
abstract fun decode()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun ofByteArray(bytes: ByteArray): ServerPacket {
|
||||||
|
|
||||||
|
val stream = DataInputStream(bytes.inputStream())
|
||||||
|
|
||||||
|
stream.skipUntil(10)
|
||||||
|
val idBytes = stream.readUntil(11)
|
||||||
|
val id = idBytes.map { it.toString(16) }.joinToString("")
|
||||||
|
|
||||||
|
return when (id) {
|
||||||
|
"08 25 31 01" -> Server0825Packet(Server0825Packet.Type.TYPE_08_25_31_01, stream);
|
||||||
|
"08 25 31 02" -> Server0825Packet(Server0825Packet.Type.TYPE_08_25_31_02, stream);
|
||||||
|
|
||||||
|
else -> throw UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun DataInputStream.skipUntil(byte: Byte) {
|
||||||
public ServerPacket(@NotNull InputStream in) {
|
while (readByte() != byte);
|
||||||
super(in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerPacket(@NotNull byte[] in) {
|
fun DataInputStream.readUntil(byte: Byte): ByteArray {
|
||||||
this(new ByteArrayInputStream(in));
|
var buff = byteArrayOf()
|
||||||
|
var b: Byte
|
||||||
|
b = readByte()
|
||||||
|
while (b != byte) {
|
||||||
|
buff += b
|
||||||
|
b = readByte()
|
||||||
|
}
|
||||||
|
return buff
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void decode();
|
fun DataInputStream.readIP(): String {
|
||||||
|
var buff = "";
|
||||||
|
for (i in 0..12) {//todo: check that
|
||||||
|
buff += readByte().toInt();
|
||||||
|
}
|
||||||
|
return buff;
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,11 @@ public final class TEAEncryption {
|
|||||||
return new _TEAEncryption().encrypt(source, key);
|
return new _TEAEncryption().encrypt(source, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] decrypt(byte[] source, byte[] key) {
|
public static byte[] decrypt(byte[] source, byte[] key) {
|
||||||
return new _TEAEncryption().decrypt(source, key);
|
return new _TEAEncryption().decrypt(source, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] decrypt(byte[] source, int offset, int length, byte[] key) {
|
public static byte[] decrypt(byte[] source, int offset, int length, byte[] key) {
|
||||||
return new _TEAEncryption().decrypt(source, offset, length, key);
|
return new _TEAEncryption().decrypt(source, offset, length, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user