Commit f0702a7e authored by Him188's avatar Him188

Add more utilities

parent 7ea0495f
...@@ -15,7 +15,7 @@ fun ByteReadPacket.readIoBuffer( ...@@ -15,7 +15,7 @@ fun ByteReadPacket.readIoBuffer(
n: Int = remaining.toInt()//not that safe but adequate n: Int = remaining.toInt()//not that safe but adequate
): IoBuffer = IoBuffer.Pool.borrow().also { this.readFully(it, n) } ): IoBuffer = IoBuffer.Pool.borrow().also { this.readFully(it, n) }
fun ByteReadPacket.readIoBuffer(n: Number) = this.readIoBuffer(n.toInt()) fun ByteReadPacket.readIoBuffer(n: Short) = this.readIoBuffer(n.toInt())
fun Input.readIP(): String = buildString(4 + 3) { fun Input.readIP(): String = buildString(4 + 3) {
repeat(4) { repeat(4) {
...@@ -25,6 +25,8 @@ fun Input.readIP(): String = buildString(4 + 3) { ...@@ -25,6 +25,8 @@ fun Input.readIP(): String = buildString(4 + 3) {
} }
} }
fun Input.readPacket(length: Int): ByteReadPacket = this.readBytes(length).toReadPacket()
fun Input.readUVarIntLVString(): String = String(this.readUVarIntByteArray()) fun Input.readUVarIntLVString(): String = String(this.readUVarIntByteArray())
fun Input.readUShortLVString(): String = String(this.readUShortLVByteArray()) fun Input.readUShortLVString(): String = String(this.readUShortLVByteArray())
...@@ -62,7 +64,14 @@ fun Input.readTLVMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMa ...@@ -62,7 +64,14 @@ fun Input.readTLVMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMa
", duplicating value=${this.readUShortLVByteArray()}" + ", duplicating value=${this.readUShortLVByteArray()}" +
", remaining=" + if (expectingEOF) this.readBytes().toUHexString() else "[Not expecting EOF]" ", remaining=" + if (expectingEOF) this.readBytes().toUHexString() else "[Not expecting EOF]"
} }
map[type.toUInt()] = this.readUShortLVByteArray() try {
map[type.toUInt()] = this.readUShortLVByteArray()
} catch (e: RuntimeException) { // BufferUnderflowException
if (expectingEOF) {
return map
}
throw e
}
} }
return map return map
} }
...@@ -103,11 +112,24 @@ fun Input.readFlatTUVarIntMap(expectingEOF: Boolean = false, tagSize: Int = 1): ...@@ -103,11 +112,24 @@ fun Input.readFlatTUVarIntMap(expectingEOF: Boolean = false, tagSize: Int = 1):
return map return map
} }
fun Map<UInt, ByteArray>.printTLVMap(name: String) = fun Map<UInt, ByteArray>.printTLVMap(name: String = "", keyLength: Int = 1) =
debugPrintln("TLVMap $name= " + this.mapValues { (_, value) -> value.toUHexString() }.mapKeys { it.key.toInt().toUShort().toUHexString() }) debugPrintln("TLVMap $name= " + this.mapValues { (_, value) -> value.toUHexString() }.mapKeys {
when (keyLength) {
1 -> it.key.toInt().toUByte().toUHexString()
2 -> it.key.toInt().toUShort().toUHexString()
4 -> it.key.toInt().toUInt().toUHexString()
else -> illegalArgument("Expecting 1, 2 or 4 for keyLength")
}
})
@Suppress("NOTHING_TO_INLINE")
internal inline fun unsupported(): Nothing = error("Unsupported")
@Suppress("NOTHING_TO_INLINE")
internal inline fun illegalArgument(message: String? = null): Nothing = error(message ?: "Illegal argument passed")
@JvmName("printTLVStringMap") @JvmName("printTLVStringMap")
fun Map<UInt, String>.printTLVMap(name: String) = fun Map<UInt, String>.printTLVMap(name: String = "") =
debugPrintln("TLVMap $name= " + this.mapKeys { it.key.toInt().toUShort().toUHexString() }) debugPrintln("TLVMap $name= " + this.mapKeys { it.key.toInt().toUShort().toUHexString() })
fun Input.readString(length: Int): String = String(this.readBytes(length)) fun Input.readString(length: Int): String = String(this.readBytes(length))
......
...@@ -4,6 +4,8 @@ package net.mamoe.mirai.utils.io ...@@ -4,6 +4,8 @@ package net.mamoe.mirai.utils.io
import kotlinx.io.core.* import kotlinx.io.core.*
import kotlinx.io.pool.useInstance import kotlinx.io.pool.useInstance
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.protobuf.ProtoBuf
import net.mamoe.mirai.contact.GroupId import net.mamoe.mirai.contact.GroupId
import net.mamoe.mirai.contact.GroupInternalId import net.mamoe.mirai.contact.GroupInternalId
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
...@@ -57,6 +59,9 @@ fun BytePacketBuilder.writeHex(uHex: String) { ...@@ -57,6 +59,9 @@ fun BytePacketBuilder.writeHex(uHex: String) {
} }
} }
fun <T> BytePacketBuilder.writeProto(serializer: SerializationStrategy<T>, obj: T) = writeFully(ProtoBuf.dump(serializer, obj))
fun BytePacketBuilder.writeTLV(tag: UByte, values: UByteArray) { fun BytePacketBuilder.writeTLV(tag: UByte, values: UByteArray) {
writeUByte(tag) writeUByte(tag)
writeUVarInt(values.size.toUInt()) writeUVarInt(values.size.toUInt())
...@@ -104,17 +109,17 @@ fun BytePacketBuilder.writeTByteArray(tag: UByte, value: UByteArray) { ...@@ -104,17 +109,17 @@ fun BytePacketBuilder.writeTByteArray(tag: UByte, value: UByteArray) {
/** /**
* 会使用 [ByteArrayPool] 缓存 * 会使用 [ByteArrayPool] 缓存
*/ */
fun BytePacketBuilder.encryptAndWrite(key: ByteArray, encoder: BytePacketBuilder.() -> Unit) = inline fun BytePacketBuilder.encryptAndWrite(key: ByteArray, encoder: BytePacketBuilder.() -> Unit) =
BytePacketBuilder().apply(encoder).build().encryptBy(key) { decrypted -> writeFully(decrypted) } BytePacketBuilder().apply(encoder).build().encryptBy(key) { decrypted -> writeFully(decrypted) }
fun BytePacketBuilder.encryptAndWrite(key: IoBuffer, encoder: BytePacketBuilder.() -> Unit) = ByteArrayPool.useInstance { inline fun BytePacketBuilder.encryptAndWrite(key: IoBuffer, encoder: BytePacketBuilder.() -> Unit) = ByteArrayPool.useInstance {
key.readFully(it, 0, key.readRemaining) key.readFully(it, 0, key.readRemaining)
encryptAndWrite(it, encoder) encryptAndWrite(it, encoder)
} }
fun BytePacketBuilder.encryptAndWrite(key: DecrypterByteArray, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(key.value, encoder) inline fun BytePacketBuilder.encryptAndWrite(key: DecrypterByteArray, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(key.value, encoder)
fun BytePacketBuilder.encryptAndWrite(keyHex: String, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(keyHex.hexToBytes(), encoder) inline fun BytePacketBuilder.encryptAndWrite(keyHex: String, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(keyHex.hexToBytes(), encoder)
fun BytePacketBuilder.writeTLV0006(qq: UInt, password: String, loginTime: Int, loginIP: String, privateKey: PrivateKey) { fun BytePacketBuilder.writeTLV0006(qq: UInt, password: String, loginTime: Int, loginIP: String, privateKey: PrivateKey) {
val firstMD5 = md5(password) val firstMD5 = md5(password)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment