diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/io/JceInput.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/io/JceInput.kt index cabecf645..2f931e376 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/io/JceInput.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/io/JceInput.kt @@ -29,6 +29,22 @@ class JceInput( return JceHead(tag = tag, type = type) } + fun read(default: Byte, tag: Int): Byte = readByteOrNull(tag) ?: default + fun read(default: Short, tag: Int): Short = readShortOrNull(tag) ?: default + fun read(default: Int, tag: Int): Int = readIntOrNull(tag) ?: default + fun read(default: Long, tag: Int): Long = readLongOrNull(tag) ?: default + fun read(default: Float, tag: Int): Float = readFloatOrNull(tag) ?: default + fun read(default: Double, tag: Int): Double = readDoubleOrNull(tag) ?: default + fun read(default: Boolean, tag: Int): Boolean = readBooleanOrNull(tag) ?: default + + fun read(default: ByteArray, tag: Int): ByteArray = readByteArrayOrNull(tag) ?: default + fun read(default: ShortArray, tag: Int): ShortArray = readShortArrayOrNull(tag) ?: default + fun read(default: IntArray, tag: Int): IntArray = readIntArrayOrNull(tag) ?: default + fun read(default: LongArray, tag: Int): LongArray = readLongArrayOrNull(tag) ?: default + fun read(default: FloatArray, tag: Int): FloatArray = readFloatArrayOrNull(tag) ?: default + fun read(default: DoubleArray, tag: Int): DoubleArray = readDoubleArrayOrNull(tag) ?: default + fun read(default: BooleanArray, tag: Int): BooleanArray = readBooleanArrayOrNull(tag) ?: default + fun readBoolean(tag: Int): Boolean = readBooleanOrNull(tag) ?: error("cannot find tag $tag") fun readByte(tag: Int): Byte = readByteOrNull(tag) ?: error("cannot find tag $tag") fun readShort(tag: Int): Short = readShortOrNull(tag) ?: error("cannot find tag $tag") @@ -176,7 +192,7 @@ class JceInput( } } - fun , K, V> readMapOrNull(defaultKey: K, defaultValue: V, tag: Int): Map? = skipToTagOrNull(tag) { + fun readMapOrNull(defaultKey: K, defaultValue: V, tag: Int): Map? = skipToTagOrNull(tag) { check(it.type.toInt() == 8) { "type mismatch" } val size = readInt(0) val map = HashMap(size) @@ -186,6 +202,16 @@ class JceInput( return map } + inline fun readMapOrNull(tag: Int): Map? = skipToTagOrNull(tag) { + check(it.type.toInt() == 8) { "type mismatch" } + val size = readInt(0) + val map = HashMap(size) + repeat(size) { + map[readSimpleObject(0)] = readSimpleObject(0) + } + return map + } + fun readListOrNull(defaultElement: T, tag: Int): List? = skipToTagOrNull(tag) { head -> check(head.type.toInt() == 9) { "type mismatch" } val size = readInt(0) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/io/JceOutput.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/io/JceOutput.kt index ba352b960..9357a05a9 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/io/JceOutput.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/io/JceOutput.kt @@ -2,21 +2,31 @@ package net.mamoe.mirai.qqandroid.network.io import kotlinx.io.charsets.Charset import kotlinx.io.core.* -import kotlinx.io.pool.useInstance -import net.mamoe.mirai.utils.io.ByteArrayPool -import net.mamoe.mirai.utils.io.readRemainingBytes import kotlin.reflect.KClass -private val CharsetGBK = Charset.forName("GBK") +@PublishedApi +internal val CharsetGBK = Charset.forName("GBK") -fun buildJcePacket(stringCharset: Charset = CharsetGBK, block: JceOutput.() -> Unit): ByteReadPacket { +inline fun buildJcePacket(stringCharset: Charset = CharsetGBK, block: JceOutput.() -> Unit): ByteReadPacket { return JceOutput(stringCharset).apply(block).build() } -fun BytePacketBuilder.writeJcePacket(stringCharset: Charset = CharsetGBK, block: JceOutput.() -> Unit) { +inline fun BytePacketBuilder.writeJcePacket(stringCharset: Charset = CharsetGBK, block: JceOutput.() -> Unit) { return this.writePacket(buildJcePacket(stringCharset, block)) } +fun jceStruct(tag: Int, struct: JceStruct): ByteArray{ + return buildJcePacket { + writeJceStruct(struct, tag) + }.readBytes() +} + +fun jceMap(tag: Int, vararg entries: Pair): ByteArray { + return buildJcePacket { + writeMap(mapOf(*entries), tag) + }.readBytes() +} + /** * * From: com.qq.taf.jce.JceOutputStream diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/jce/RequestPacket.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/jce/RequestPacket.kt index f34ad0887..649eae846 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/jce/RequestPacket.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/jce/RequestPacket.kt @@ -6,21 +6,55 @@ import net.mamoe.mirai.qqandroid.network.io.JceStruct private val EMPTY_MAP = mapOf() -class RequestPacket( - val sBuffer: ByteArray, - val cPacketType: Byte = 0, - val iMessageType: Int = 0, - val iRequestId: Int = 0, - val iTimeout: Int = 3000, - val iVersion: Short = 3, - val context: Map = EMPTY_MAP, - val sFuncName: String = "", - val sServantName: String = "", - val status: Map = EMPTY_MAP -) : JceStruct() { +class RequestPacket() : JceStruct() { + lateinit var sBuffer: ByteArray + var cPacketType: Byte = 0 + var iMessageType: Int = 0 + var iRequestId: Int = 0 + var iTimeout: Int = 3000 + var iVersion: Short = 3 + var context: Map = EMPTY_MAP + var sFuncName: String = "" + var sServantName: String = "" + var status: Map = EMPTY_MAP + + constructor( + sBuffer: ByteArray, + cPacketType: Byte = 0, + iMessageType: Int = 0, + iRequestId: Int = 0, + iTimeout: Int = 3000, + iVersion: Short = 3, + context: Map = EMPTY_MAP, + sFuncName: String = "", + sServantName: String = "", + status: Map = EMPTY_MAP + ) : this() { + this.sBuffer = sBuffer + this.cPacketType = cPacketType + this.iMessageType = iMessageType + this.iRequestId = iRequestId + this.iTimeout = iTimeout + this.iVersion = iVersion + this.context = context + this.sFuncName = sFuncName + this.sServantName = sServantName + this.status = status + } + companion object : Factory { override fun newInstanceFrom(input: JceInput): RequestPacket { - TODO("not implemented") + val iVersion = input.readShort(1) + val cPacketType = input.readByte(2) + val iMessageType = input.readInt(3) + val iRequestId = input.readInt(4) + val sServantName = input.readString(5) + val sFuncName = input.readString(6) + val sBuffer = input.readByteArray(7) + val iTimeout = input.readInt(8) + val context = input.readMap("", "", 9) + val status = input.readMap("", "", 10) + return RequestPacket(sBuffer, cPacketType, iMessageType, iRequestId, iTimeout, iVersion, context, sFuncName, sServantName, status) } } diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/jce/uni.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/jce/uni.kt index d68d3fb42..80d671141 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/jce/uni.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/jce/uni.kt @@ -5,8 +5,8 @@ import net.mamoe.mirai.qqandroid.network.io.JceOutput import net.mamoe.mirai.qqandroid.network.io.buildJcePacket import net.mamoe.mirai.qqandroid.network.io.writeJcePacket -fun BytePacketBuilder.writeUniRequestPacket(requestPacket: RequestPacket) { +inline fun BytePacketBuilder.writeUniRequestPacket(requestPacket: RequestPacket.() -> Unit) { writeJcePacket { - requestPacket.writeTo(this) + RequestPacket().apply(requestPacket).writeTo(this) } } \ No newline at end of file diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt index 54ed76d7c..e6f8553ae 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt @@ -81,6 +81,8 @@ internal object KnownPacketFactories : List> by mutableListOf( } else -> error("Illegal flag2. Expected 0x02, got $flag2") } + // 00 00 00 60 00 00 00 0B 02 00 00 00 00 0E 31 39 39 34 37 30 31 30 32 31 CE 35 53 19 84 A8 1A B8 5B 48 E3 7C D0 A6 BA 58 6A EB CE 50 B9 A0 98 D5 B9 D0 1C 72 E2 86 24 FC 55 44 6C 6E E3 F9 15 6C EC 6C 6B 94 40 F7 B4 45 CF B4 D0 79 84 FE 30 EA 98 84 44 84 02 32 70 DD D7 07 07 72 DE 87 59 AC + 0x0B -> else -> error("Illegal flag1. Expected 0x0A or 0x0B, got $flag1") } } diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/SvcReqRegisterPacket.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/SvcReqRegisterPacket.kt index ee3e17b3f..04dc823e9 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/SvcReqRegisterPacket.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/SvcReqRegisterPacket.kt @@ -1,13 +1,12 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.login import kotlinx.io.core.ByteReadPacket -import kotlinx.io.core.readBytes import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.data.Packet import net.mamoe.mirai.qqandroid.QQAndroidBot import net.mamoe.mirai.qqandroid.network.QQAndroidClient -import net.mamoe.mirai.qqandroid.network.io.buildJcePacket -import net.mamoe.mirai.qqandroid.network.protocol.jce.RequestPacket +import net.mamoe.mirai.qqandroid.network.io.jceMap +import net.mamoe.mirai.qqandroid.network.io.jceStruct import net.mamoe.mirai.qqandroid.network.protocol.jce.SvcReqRegister import net.mamoe.mirai.qqandroid.network.protocol.jce.writeUniRequestPacket import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket @@ -38,73 +37,63 @@ internal object SvcReqRegisterPacket : PacketFactory