Commit a9740240 authored by Him188's avatar Him188

Merge remote-tracking branch 'origin/master'

parents 9cce64bc 5b8dbf59
...@@ -3,6 +3,8 @@ package net.mamoe.mirai.qqandroid.io ...@@ -3,6 +3,8 @@ package net.mamoe.mirai.qqandroid.io
import kotlinx.io.charsets.Charset import kotlinx.io.charsets.Charset
import kotlinx.io.core.* import kotlinx.io.core.*
import kotlinx.io.pool.ObjectPool import kotlinx.io.pool.ObjectPool
import kotlinx.serialization.DeserializationStrategy
import net.mamoe.mirai.qqandroid.io.serialization.Jce
import net.mamoe.mirai.qqandroid.network.protocol.jce.RequestPacket import net.mamoe.mirai.qqandroid.network.protocol.jce.RequestPacket
import net.mamoe.mirai.utils.io.DebugLogger import net.mamoe.mirai.utils.io.DebugLogger
import net.mamoe.mirai.utils.io.readIoBuffer import net.mamoe.mirai.utils.io.readIoBuffer
...@@ -18,12 +20,16 @@ inline class JceHead(private val value: Long) { ...@@ -18,12 +20,16 @@ inline class JceHead(private val value: Long) {
override fun toString(): String { override fun toString(): String {
return "JceHead(tag=$tag, type=$type)" return "JceHead(tag=$tag, type=$type)"
} }Z
} }
fun <J : JceStruct> ByteArray.readJceStruct(factory: JceStruct.Factory<J>, tag: Int = 0, charset: Charset = CharsetUTF8): J { fun <J : JceStruct> ByteArray.readJceStruct(
deserializer: DeserializationStrategy<J>,
tag: Int = 0,
charset: Charset = CharsetUTF8
): J {
this.asJceInput(charset).use { this.asJceInput(charset).use {
return it.readJceStruct(factory, tag) return Jce.byCharSet(charset).load(deserializer, this.)
} }
} }
...@@ -55,7 +61,10 @@ fun <J : JceStruct> ByteReadPacket.readJceRequestBufferMapVersion3ToJceStruct(fa ...@@ -55,7 +61,10 @@ fun <J : JceStruct> ByteReadPacket.readJceRequestBufferMapVersion3ToJceStruct(fa
fun ByteReadPacket.readJceRequestBufferMapVersion2(charset: Charset = CharsetUTF8): Map<String, ByteArray> { fun ByteReadPacket.readJceRequestBufferMapVersion2(charset: Charset = CharsetUTF8): Map<String, ByteArray> {
this.use { this.use {
discardExact(8) discardExact(8)
val request = this.asJceInput(charset).use { RequestPacket.newInstanceFrom(it) } val request = this.asJceInput(charset).use {
Jce
RequestPacket.serializer()
}
val map = request.sBuffer.asJceInput(charset).withUse { val map = request.sBuffer.asJceInput(charset).withUse {
readNestedMap<String, String, ByteArray>(0) readNestedMap<String, String, ByteArray>(0)
} }
......
package net.mamoe.mirai.qqandroid.io package net.mamoe.mirai.qqandroid.io
abstract class JceStruct { interface JceStruct {
abstract fun writeTo(builder: JceOutput)
interface Factory<out T : JceStruct> {
fun newInstanceFrom(input: JceInput): T
}
} }
\ No newline at end of file
...@@ -10,6 +10,7 @@ import kotlinx.serialization.* ...@@ -10,6 +10,7 @@ import kotlinx.serialization.*
import kotlinx.serialization.internal.* import kotlinx.serialization.internal.*
import kotlinx.serialization.modules.EmptyModule import kotlinx.serialization.modules.EmptyModule
import kotlinx.serialization.modules.SerialModule import kotlinx.serialization.modules.SerialModule
import net.mamoe.mirai.qqandroid.io.CharsetUTF8
import net.mamoe.mirai.qqandroid.io.JceEncodeException import net.mamoe.mirai.qqandroid.io.JceEncodeException
import net.mamoe.mirai.qqandroid.io.JceStruct import net.mamoe.mirai.qqandroid.io.JceStruct
import kotlin.reflect.KClass import kotlin.reflect.KClass
...@@ -321,6 +322,14 @@ class Jce private constructor(private val charset: JceCharset, context: SerialMo ...@@ -321,6 +322,14 @@ class Jce private constructor(private val charset: JceCharset, context: SerialMo
val UTF8 = Jce(JceCharset.UTF8) val UTF8 = Jce(JceCharset.UTF8)
val GBK = Jce(JceCharset.GBK) val GBK = Jce(JceCharset.GBK)
public fun byCharSet(c: Charset): Jce {
return if (c === CharsetUTF8) {
UTF8
} else {
GBK
}
}
internal const val BYTE: Int = 0 internal const val BYTE: Int = 0
internal const val DOUBLE: Int = 5 internal const val DOUBLE: Int = 5
internal const val FLOAT: Int = 4 internal const val FLOAT: Int = 4
......
package net.mamoe.mirai.qqandroid.network.protocol.jce package net.mamoe.mirai.qqandroid.network.protocol.jce
import net.mamoe.mirai.qqandroid.io.JceInput import kotlinx.serialization.SerialId
import net.mamoe.mirai.qqandroid.io.JceOutput import kotlinx.serialization.Serializable
import net.mamoe.mirai.qqandroid.io.JceStruct import net.mamoe.mirai.qqandroid.io.JceStruct
import net.mamoe.mirai.utils.cryptor.contentToString import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
private val EMPTY_MAP = mapOf<String, String>() private val EMPTY_MAP = mapOf<String, String>()
class RequestPacket() : JceStruct() { @Serializable
lateinit var sBuffer: ByteArray class RequestPacket(
var cPacketType: Byte = 0 @SerialId(1) val iVersion: Short = 3,
var iMessageType: Int = 0 @SerialId(2) val cPacketType: Byte = 0,
var iRequestId: Int = 0 @SerialId(3) val iMessageType: Int = 0,
var iTimeout: Int = 0 @SerialId(4) val iRequestId: Int = 0,
var iVersion: Short = 3 @SerialId(5) val sServantName: String = "",
var context: Map<String, String> = EMPTY_MAP @SerialId(6) val sFuncName: String = "",
var sFuncName: String = "" @SerialId(7) val sBuffer: ByteArray = EMPTY_BYTE_ARRAY,
var sServantName: String = "" @SerialId(8) val iTimeout: Int = 0,
var status: Map<String, String> = EMPTY_MAP @SerialId(9) val context: Map<String, String> = EMPTY_MAP,
@SerialId(10) val status: Map<String, String> = EMPTY_MAP
constructor( ) : JceStruct
sBuffer: ByteArray, \ No newline at end of file
cPacketType: Byte = 0,
iMessageType: Int = 0,
iRequestId: Int = 0,
iTimeout: Int = 0,
iVersion: Short = 3,
context: Map<String, String> = EMPTY_MAP,
sFuncName: String = "",
sServantName: String = "",
status: Map<String, String> = 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<RequestPacket> {
override fun newInstanceFrom(input: JceInput): RequestPacket {
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)
}
}
override fun writeTo(builder: JceOutput) {
builder.write(this.iVersion, 1)
builder.write(this.cPacketType, 2)
builder.write(this.iMessageType, 3)
builder.write(this.iRequestId, 4)
builder.write(this.sServantName, 5)
builder.write(this.sFuncName, 6)
builder.write(this.sBuffer, 7)
builder.write(this.iTimeout, 8)
builder.write(this.context, 9)
builder.write(this.status, 10)
}
override fun toString(): String {
return this.contentToString()
}
}
\ No newline at end of file
package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.data package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.data
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.qqandroid.io.JceInput
import net.mamoe.mirai.qqandroid.io.JceOutput
import net.mamoe.mirai.qqandroid.io.JceStruct import net.mamoe.mirai.qqandroid.io.JceStruct
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
class RequestPushNotify( @Serializable
val uin: Long, internal class RequestPushNotify(
val ctype: Byte, @SerialId(0) val uin: Long = 0L,
val strService: String, @SerialId(1) val ctype: Byte = 0,
val strCmd: String, @SerialId(2) val strService: String?,
val vNotifyCookie: ByteArray, @SerialId(3) val strCmd: String?,
val usMsgType: Int, @SerialId(4) val vNotifyCookie: ByteArray = EMPTY_BYTE_ARRAY,
val wUserActive: Int, @SerialId(5) val usMsgType: Int?,
val wGeneralFlag: Int, @SerialId(6) val wUserActive: Int?,
val bindedUin: Long, @SerialId(7) val wGeneralFlag: Int?,
val stMsgInfo: MsgInfo, @SerialId(8) val bindedUin: Long?,
val msgCtrlBuf: String, @SerialId(9) val stMsgInfo: MsgInfo?,
val serverBuf: ByteArray, @SerialId(10) val msgCtrlBuf: String?,
val pingFlag: Long, @SerialId(11) val serverBuf: ByteArray?,
val svrip: Int @SerialId(12) val pingFlag: Long?,
) : Packet, JceStruct() { @SerialId(13) val svrip: Int?
override fun writeTo(builder: JceOutput) { ) : JceStruct, Packet
//not needed
} @Serializable
internal class MsgInfo(
companion object : Factory<RequestPushNotify> { @SerialId(0) val lFromUin: Long = 0L,
override fun newInstanceFrom(input: JceInput): RequestPushNotify { @SerialId(1) val uMsgTime: Long = 0L,
return RequestPushNotify( @SerialId(2) val shMsgType: Short?,
input.read(0L, 0), @SerialId(3) val shMsgSeq: Short?,
input.read(0.toByte(), 1), @SerialId(4) val strMsg: String?,
input.readString(2), @SerialId(5) val uRealMsgTime: Int?,
input.readString(3), @SerialId(6) val vMsg: ByteArray?,
input.read(EMPTY_BYTE_ARRAY, 4), @SerialId(7) val uAppShareID: Long?,
input.read(0, 5), @SerialId(8) val vMsgCookies: ByteArray = EMPTY_BYTE_ARRAY,
input.read(0, 6), @SerialId(9) val vAppShareCookie: ByteArray = EMPTY_BYTE_ARRAY,
input.read(0, 7), @SerialId(10) val lMsgUid: Long?,
input.read(0L, 8), @SerialId(11) val lLastChangeTime: Long?,
input.readJceStruct(MsgInfo, 9), @SerialId(12) val vCPicInfo: List<CPicInfo>?,
input.readString(10), @SerialId(13) val stShareData: ShareData?,
input.readByteArray(11), @SerialId(14) val lFromInstId: Long?,
input.readLong(12), @SerialId(15) val vRemarkOfSender: ByteArray?,
input.readInt(13) @SerialId(16) val strFromMobile: String?,
) @SerialId(17) val strFromName: String?,
} @SerialId(18) val vNickName: List<String>?,
} @SerialId(19) val stC2CTmpMsgHead: TempMsgHead?
) : JceStruct
}
class MsgInfo( @Serializable
val lFromUin: Long,
val uMsgTime: Long,
val shMsgType: Short,
val shMsgSeq: Short,
val strMsg: String,
val uRealMsgTime: Int,
val vMsg: ByteArray,
val uAppShareID: Long,
val vMsgCookies: ByteArray,
val vAppShareCookie: ByteArray,
val lMsgUid: Long,
val lLastChangeTime: Long,
val vCPicInfo: List<CPicInfo>,
val stShareData: ShareData,
val lFromInstId: Long,
val vRemarkOfSender: ByteArray,
val strFromMobile: String,
val strFromName: String,
val vNickName: List<String>,
val stC2CTmpMsgHead: TempMsgHead?
) : JceStruct() {
companion object : Factory<MsgInfo> {
override fun newInstanceFrom(input: JceInput): MsgInfo = with(input) {
return MsgInfo(
readLong(0),
readLong(1),
readShort(2),
readShort(3),
readString(4),
readInt(5),
readByteArray(6),
readLong(7),
readByteArray(8),
readByteArray(9),
readLong(10),
readLong(11),
readJceStructList(CPicInfo, 12),
readJceStruct(ShareData, 13),
readLong(14),
readByteArray(15),
readString(16),
readString(17),
readList(18),
readJceStructOrNull(TempMsgHead, 19)
)
}
}
override fun writeTo(builder: JceOutput) {
// not needed
}
}
class ShareData( class ShareData(
val pkgname: String = "", @SerialId(0) val pkgname: String = "",
val msgtail: String = "", @SerialId(1) val msgtail: String = "",
val picurl: String = "", @SerialId(2) val picurl: String = "",
val url: String = "" @SerialId(3) val url: String = ""
) : JceStruct() { ) : JceStruct
companion object : Factory<ShareData> {
override fun newInstanceFrom(input: JceInput): ShareData {
return ShareData(
input.readString(0),
input.readString(1),
input.readString(2),
input.readString(3)
)
}
}
override fun writeTo(builder: JceOutput) {
// not needed
}
}
@Serializable
class TempMsgHead( class TempMsgHead(
val c2c_type: Int, @SerialId(0) val c2c_type: Int = 0,
val serviceType: Int @SerialId(1) val serviceType: Int = 0
) : JceStruct() { ) : JceStruct
override fun writeTo(builder: JceOutput) {
}
companion object : Factory<TempMsgHead> {
override fun newInstanceFrom(input: JceInput): TempMsgHead {
return TempMsgHead(
input.readInt(0),
input.readInt(1)
)
}
}
}
@Serializable
class CPicInfo( class CPicInfo(
val vPath: ByteArray, @SerialId(0) val vPath: ByteArray = EMPTY_BYTE_ARRAY,
val vHost: ByteArray? @SerialId(1) val vHost: ByteArray = EMPTY_BYTE_ARRAY
) : JceStruct() { ) : JceStruct
override fun writeTo(builder: JceOutput) { \ No newline at end of file
}
companion object : Factory<CPicInfo> {
override fun newInstanceFrom(input: JceInput): CPicInfo {
return CPicInfo(
input.readByteArray(0),
input.readByteArray(1)
)
}
}
}
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