Merge remote-tracking branch 'origin/master'

This commit is contained in:
Him188 2020-01-27 23:00:49 +08:00
commit a974024043
5 changed files with 95 additions and 232 deletions

View File

@ -3,6 +3,8 @@ package net.mamoe.mirai.qqandroid.io
import kotlinx.io.charsets.Charset
import kotlinx.io.core.*
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.utils.io.DebugLogger
import net.mamoe.mirai.utils.io.readIoBuffer
@ -18,12 +20,16 @@ inline class JceHead(private val value: Long) {
override fun toString(): String {
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 {
return it.readJceStruct(factory, tag)
return Jce.byCharSet(charset).load(deserializer, this.)
}
}
@ -55,7 +61,10 @@ fun <J : JceStruct> ByteReadPacket.readJceRequestBufferMapVersion3ToJceStruct(fa
fun ByteReadPacket.readJceRequestBufferMapVersion2(charset: Charset = CharsetUTF8): Map<String, ByteArray> {
this.use {
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 {
readNestedMap<String, String, ByteArray>(0)
}

View File

@ -1,10 +1,5 @@
package net.mamoe.mirai.qqandroid.io
abstract class JceStruct {
abstract fun writeTo(builder: JceOutput)
interface JceStruct {
interface Factory<out T : JceStruct> {
fun newInstanceFrom(input: JceInput): T
}
}

View File

@ -10,6 +10,7 @@ import kotlinx.serialization.*
import kotlinx.serialization.internal.*
import kotlinx.serialization.modules.EmptyModule
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.JceStruct
import kotlin.reflect.KClass
@ -321,6 +322,14 @@ class Jce private constructor(private val charset: JceCharset, context: SerialMo
val UTF8 = Jce(JceCharset.UTF8)
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 DOUBLE: Int = 5
internal const val FLOAT: Int = 4

View File

@ -1,78 +1,22 @@
package net.mamoe.mirai.qqandroid.network.protocol.jce
import net.mamoe.mirai.qqandroid.io.JceInput
import net.mamoe.mirai.qqandroid.io.JceOutput
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable
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>()
class RequestPacket() : JceStruct() {
lateinit var sBuffer: ByteArray
var cPacketType: Byte = 0
var iMessageType: Int = 0
var iRequestId: Int = 0
var iTimeout: Int = 0
var iVersion: Short = 3
var context: Map<String, String> = EMPTY_MAP
var sFuncName: String = ""
var sServantName: String = ""
var status: Map<String, String> = EMPTY_MAP
constructor(
sBuffer: ByteArray,
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()
}
}
@Serializable
class RequestPacket(
@SerialId(1) val iVersion: Short = 3,
@SerialId(2) val cPacketType: Byte = 0,
@SerialId(3) val iMessageType: Int = 0,
@SerialId(4) val iRequestId: Int = 0,
@SerialId(5) val sServantName: String = "",
@SerialId(6) val sFuncName: String = "",
@SerialId(7) val sBuffer: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(8) val iTimeout: Int = 0,
@SerialId(9) val context: Map<String, String> = EMPTY_MAP,
@SerialId(10) val status: Map<String, String> = EMPTY_MAP
) : JceStruct

View File

@ -1,164 +1,70 @@
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.qqandroid.io.JceInput
import net.mamoe.mirai.qqandroid.io.JceOutput
import net.mamoe.mirai.qqandroid.io.JceStruct
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
class RequestPushNotify(
val uin: Long,
val ctype: Byte,
val strService: String,
val strCmd: String,
val vNotifyCookie: ByteArray,
val usMsgType: Int,
val wUserActive: Int,
val wGeneralFlag: Int,
val bindedUin: Long,
val stMsgInfo: MsgInfo,
val msgCtrlBuf: String,
val serverBuf: ByteArray,
val pingFlag: Long,
val svrip: Int
) : Packet, JceStruct() {
override fun writeTo(builder: JceOutput) {
//not needed
}
@Serializable
internal class RequestPushNotify(
@SerialId(0) val uin: Long = 0L,
@SerialId(1) val ctype: Byte = 0,
@SerialId(2) val strService: String?,
@SerialId(3) val strCmd: String?,
@SerialId(4) val vNotifyCookie: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(5) val usMsgType: Int?,
@SerialId(6) val wUserActive: Int?,
@SerialId(7) val wGeneralFlag: Int?,
@SerialId(8) val bindedUin: Long?,
@SerialId(9) val stMsgInfo: MsgInfo?,
@SerialId(10) val msgCtrlBuf: String?,
@SerialId(11) val serverBuf: ByteArray?,
@SerialId(12) val pingFlag: Long?,
@SerialId(13) val svrip: Int?
) : JceStruct, Packet
companion object : Factory<RequestPushNotify> {
override fun newInstanceFrom(input: JceInput): RequestPushNotify {
return RequestPushNotify(
input.read(0L, 0),
input.read(0.toByte(), 1),
input.readString(2),
input.readString(3),
input.read(EMPTY_BYTE_ARRAY, 4),
input.read(0, 5),
input.read(0, 6),
input.read(0, 7),
input.read(0L, 8),
input.readJceStruct(MsgInfo, 9),
input.readString(10),
input.readByteArray(11),
input.readLong(12),
input.readInt(13)
)
}
}
@Serializable
internal class MsgInfo(
@SerialId(0) val lFromUin: Long = 0L,
@SerialId(1) val uMsgTime: Long = 0L,
@SerialId(2) val shMsgType: Short?,
@SerialId(3) val shMsgSeq: Short?,
@SerialId(4) val strMsg: String?,
@SerialId(5) val uRealMsgTime: Int?,
@SerialId(6) val vMsg: ByteArray?,
@SerialId(7) val uAppShareID: Long?,
@SerialId(8) val vMsgCookies: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(9) val vAppShareCookie: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(10) val lMsgUid: Long?,
@SerialId(11) val lLastChangeTime: Long?,
@SerialId(12) val vCPicInfo: List<CPicInfo>?,
@SerialId(13) val stShareData: ShareData?,
@SerialId(14) val lFromInstId: Long?,
@SerialId(15) val vRemarkOfSender: ByteArray?,
@SerialId(16) val strFromMobile: String?,
@SerialId(17) val strFromName: String?,
@SerialId(18) val vNickName: List<String>?,
@SerialId(19) val stC2CTmpMsgHead: TempMsgHead?
) : JceStruct
}
class MsgInfo(
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
}
}
@Serializable
class ShareData(
val pkgname: String = "",
val msgtail: String = "",
val picurl: String = "",
val url: String = ""
) : 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
}
}
@SerialId(0) val pkgname: String = "",
@SerialId(1) val msgtail: String = "",
@SerialId(2) val picurl: String = "",
@SerialId(3) val url: String = ""
) : JceStruct
@Serializable
class TempMsgHead(
val c2c_type: Int,
val serviceType: Int
) : JceStruct() {
override fun writeTo(builder: JceOutput) {
}
companion object : Factory<TempMsgHead> {
override fun newInstanceFrom(input: JceInput): TempMsgHead {
return TempMsgHead(
input.readInt(0),
input.readInt(1)
)
}
}
}
@SerialId(0) val c2c_type: Int = 0,
@SerialId(1) val serviceType: Int = 0
) : JceStruct
@Serializable
class CPicInfo(
val vPath: ByteArray,
val vHost: ByteArray?
) : JceStruct() {
override fun writeTo(builder: JceOutput) {
}
companion object : Factory<CPicInfo> {
override fun newInstanceFrom(input: JceInput): CPicInfo {
return CPicInfo(
input.readByteArray(0),
input.readByteArray(1)
)
}
}
}
@SerialId(0) val vPath: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(1) val vHost: ByteArray = EMPTY_BYTE_ARRAY
) : JceStruct