Commit 99ffba28 authored by Him188's avatar Him188 Committed by GitHub

Merge pull request #120 from mamoe/kotlin-1.3.70

Kotlin 1.3.70
parents 200b8b98 c69cb6f3
...@@ -18,7 +18,8 @@ buildscript { ...@@ -18,7 +18,8 @@ buildscript {
classpath("com.android.tools.build:gradle:3.5.3") classpath("com.android.tools.build:gradle:3.5.3")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
classpath("com.github.jengelman.gradle.plugins:shadow:5.2.0") classpath("com.github.jengelman.gradle.plugins:shadow:5.2.0")
classpath("org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion") @kotlin.Suppress("GradleDependency") // 1.3.70 有 bug, 无法编译添加 SerialInfo
classpath("org.jetbrains.kotlin:kotlin-serialization:1.3.61") // 不要用 $kotlinVersion
classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:$atomicFuVersion") classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:$atomicFuVersion")
} }
} }
......
...@@ -5,9 +5,9 @@ miraiVersion=0.26.0 ...@@ -5,9 +5,9 @@ miraiVersion=0.26.0
kotlin.incremental.multiplatform=true kotlin.incremental.multiplatform=true
kotlin.parallel.tasks.in.project=true kotlin.parallel.tasks.in.project=true
# kotlin # kotlin
kotlinVersion=1.3.61 kotlinVersion=1.3.70
# kotlin libraries # kotlin libraries
serializationVersion=0.14.0 serializationVersion=0.20.0-1.3.70-eap-274-2
coroutinesVersion=1.3.3 coroutinesVersion=1.3.3
atomicFuVersion=0.14.1 atomicFuVersion=0.14.1
kotlinXIoVersion=0.1.16 kotlinXIoVersion=0.1.16
......
...@@ -75,6 +75,7 @@ kotlin { ...@@ -75,6 +75,7 @@ kotlin {
commonMain { commonMain {
dependencies { dependencies {
api(kotlinx("serialization-runtime-common", serializationVersion)) api(kotlinx("serialization-runtime-common", serializationVersion))
api(kotlinx("serialization-protobuf-common", serializationVersion))
} }
} }
commonTest { commonTest {
...@@ -88,6 +89,7 @@ kotlin { ...@@ -88,6 +89,7 @@ kotlin {
if (isAndroidSDKAvailable) { if (isAndroidSDKAvailable) {
val androidMain by getting { val androidMain by getting {
dependencies { dependencies {
api(kotlinx("serialization-protobuf", serializationVersion))
} }
} }
......
...@@ -21,7 +21,7 @@ import net.mamoe.mirai.utils.MiraiInternalAPI ...@@ -21,7 +21,7 @@ import net.mamoe.mirai.utils.MiraiInternalAPI
*/ */
@Suppress("INAPPLICABLE_JVM_NAME") @Suppress("INAPPLICABLE_JVM_NAME")
actual object QQAndroid : BotFactory { actual object QQAndroid : BotFactory {
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
@JvmName("newBot") @JvmName("newBot")
actual override fun Bot(context: Context, qq: Long, password: String, configuration: BotConfiguration): Bot { actual override fun Bot(context: Context, qq: Long, password: String, configuration: BotConfiguration): Bot {
return QQAndroidBot(context, BotAccount(qq, password), configuration) return QQAndroidBot(context, BotAccount(qq, password), configuration)
...@@ -30,7 +30,7 @@ actual object QQAndroid : BotFactory { ...@@ -30,7 +30,7 @@ actual object QQAndroid : BotFactory {
/** /**
* 使用指定的 [配置][configuration] 构造 [Bot] 实例 * 使用指定的 [配置][configuration] 构造 [Bot] 实例
*/ */
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
@JvmName("newBot") @JvmName("newBot")
actual override fun Bot( actual override fun Bot(
context: Context, context: Context,
......
...@@ -24,7 +24,7 @@ import net.mamoe.mirai.utils.io.ByteArrayPool ...@@ -24,7 +24,7 @@ import net.mamoe.mirai.utils.io.ByteArrayPool
import net.mamoe.mirai.utils.io.toReadPacket import net.mamoe.mirai.utils.io.toReadPacket
import java.nio.ByteBuffer import java.nio.ByteBuffer
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
internal actual class QQAndroidBot internal actual class QQAndroidBot
actual constructor( actual constructor(
context: Context, context: Context,
...@@ -32,7 +32,7 @@ actual constructor( ...@@ -32,7 +32,7 @@ actual constructor(
configuration: BotConfiguration configuration: BotConfiguration
) : QQAndroidBotBase(context, account, configuration) ) : QQAndroidBotBase(context, account, configuration)
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
internal actual fun ByteReadChannel.toKotlinByteReadChannel(): kotlinx.coroutines.io.ByteReadChannel { internal actual fun ByteReadChannel.toKotlinByteReadChannel(): kotlinx.coroutines.io.ByteReadChannel {
return object : kotlinx.coroutines.io.ByteReadChannel { return object : kotlinx.coroutines.io.ByteReadChannel {
...@@ -144,7 +144,7 @@ internal actual fun ByteReadChannel.toKotlinByteReadChannel(): kotlinx.coroutine ...@@ -144,7 +144,7 @@ internal actual fun ByteReadChannel.toKotlinByteReadChannel(): kotlinx.coroutine
return this@toKotlinByteReadChannel.readRemaining(limit, headerSizeHint).readBytes().toReadPacket() return this@toKotlinByteReadChannel.readRemaining(limit, headerSizeHint).readBytes().toReadPacket()
} }
@UseExperimental(ExperimentalIoApi::class) @OptIn(ExperimentalIoApi::class)
@ExperimentalIoApi @ExperimentalIoApi
override fun readSession(consumer: ReadSession.() -> Unit) { override fun readSession(consumer: ReadSession.() -> Unit) {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
......
...@@ -358,7 +358,7 @@ internal class MemberInfoImpl( ...@@ -358,7 +358,7 @@ internal class MemberInfoImpl(
override val muteTimestamp: Int = jceInfo.dwShutupTimestap?.toInt() ?: 0 override val muteTimestamp: Int = jceInfo.dwShutupTimestap?.toInt() ?: 0
} }
@UseExperimental(ExperimentalContracts::class) @OptIn(ExperimentalContracts::class)
internal fun GroupImpl.Companion.checkIsInstance(expression: Boolean) { internal fun GroupImpl.Companion.checkIsInstance(expression: Boolean) {
contract { contract {
returns() implies expression returns() implies expression
...@@ -367,13 +367,14 @@ internal fun GroupImpl.Companion.checkIsInstance(expression: Boolean) { ...@@ -367,13 +367,14 @@ internal fun GroupImpl.Companion.checkIsInstance(expression: Boolean) {
} }
@Suppress("PropertyName") @Suppress("PropertyName")
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
internal class GroupImpl( internal class GroupImpl(
bot: QQAndroidBot, override val coroutineContext: CoroutineContext, bot: QQAndroidBot, override val coroutineContext: CoroutineContext,
override val id: Long, override val id: Long,
groupInfo: GroupInfo, groupInfo: GroupInfo,
members: Sequence<MemberInfo> members: Sequence<MemberInfo>
) : Group() { ) : Group() {
@Suppress("\"RemoveEmptyClassBody\"") // things will go wrong after removal, don't try
companion object { companion object {
} }
...@@ -383,7 +384,7 @@ internal class GroupImpl( ...@@ -383,7 +384,7 @@ internal class GroupImpl(
override lateinit var owner: Member override lateinit var owner: Member
@UseExperimental(MiraiExperimentalAPI::class) @OptIn(MiraiExperimentalAPI::class)
override val botAsMember: Member by lazy { override val botAsMember: Member by lazy {
Member(object : MemberInfo { Member(object : MemberInfo {
override val nameCard: String override val nameCard: String
...@@ -401,7 +402,7 @@ internal class GroupImpl( ...@@ -401,7 +402,7 @@ internal class GroupImpl(
}) })
} }
@UseExperimental(MiraiExperimentalAPI::class) @OptIn(MiraiExperimentalAPI::class)
override lateinit var botPermission: MemberPermission override lateinit var botPermission: MemberPermission
var _botMuteTimestamp: Int = groupInfo.botMuteRemaining var _botMuteTimestamp: Int = groupInfo.botMuteRemaining
...@@ -557,10 +558,10 @@ internal class GroupImpl( ...@@ -557,10 +558,10 @@ internal class GroupImpl(
TODO("not implemented") TODO("not implemented")
} }
@UseExperimental(MiraiExperimentalAPI::class) @OptIn(MiraiExperimentalAPI::class)
override fun Member(memberInfo: MemberInfo): Member { override fun Member(memberInfo: MemberInfo): Member {
return MemberImpl( return MemberImpl(
@UseExperimental(LowLevelAPI::class) @OptIn(LowLevelAPI::class)
bot._lowLevelNewQQ(memberInfo) as QQImpl, bot._lowLevelNewQQ(memberInfo) as QQImpl,
this, this,
this.coroutineContext, this.coroutineContext,
......
...@@ -36,14 +36,14 @@ import net.mamoe.mirai.utils.* ...@@ -36,14 +36,14 @@ import net.mamoe.mirai.utils.*
import kotlin.collections.asSequence import kotlin.collections.asSequence
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
internal expect class QQAndroidBot constructor( internal expect class QQAndroidBot constructor(
context: Context, context: Context,
account: BotAccount, account: BotAccount,
configuration: BotConfiguration configuration: BotConfiguration
) : QQAndroidBotBase ) : QQAndroidBotBase
@UseExperimental(MiraiInternalAPI::class, MiraiExperimentalAPI::class) @OptIn(MiraiInternalAPI::class, MiraiExperimentalAPI::class)
internal abstract class QQAndroidBotBase constructor( internal abstract class QQAndroidBotBase constructor(
context: Context, context: Context,
account: BotAccount, account: BotAccount,
...@@ -69,7 +69,7 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -69,7 +69,7 @@ internal abstract class QQAndroidBotBase constructor(
override val friends: ContactList<QQ> = ContactList(LockFreeLinkedList()) override val friends: ContactList<QQ> = ContactList(LockFreeLinkedList())
override val selfQQ: QQ by lazy { override val selfQQ: QQ by lazy {
@UseExperimental(LowLevelAPI::class) @OptIn(LowLevelAPI::class)
_lowLevelNewQQ(object : FriendInfo { _lowLevelNewQQ(object : FriendInfo {
override val uin: Long get() = this@QQAndroidBotBase.uin override val uin: Long get() = this@QQAndroidBotBase.uin
override val nick: String get() = this@QQAndroidBotBase.nick override val nick: String get() = this@QQAndroidBotBase.nick
...@@ -101,7 +101,7 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -101,7 +101,7 @@ internal abstract class QQAndroidBotBase constructor(
return groups.delegate.getOrNull(uin) return groups.delegate.getOrNull(uin)
} }
@UseExperimental(LowLevelAPI::class) @OptIn(LowLevelAPI::class)
override suspend fun _lowLevelQueryGroupList(): Sequence<Long> { override suspend fun _lowLevelQueryGroupList(): Sequence<Long> {
return network.run { return network.run {
FriendList.GetTroopListSimplify(bot.client) FriendList.GetTroopListSimplify(bot.client)
...@@ -109,7 +109,7 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -109,7 +109,7 @@ internal abstract class QQAndroidBotBase constructor(
}.groups.asSequence().map { it.groupUin.shl(32) and it.groupCode } }.groups.asSequence().map { it.groupUin.shl(32) and it.groupCode }
} }
@UseExperimental(LowLevelAPI::class) @OptIn(LowLevelAPI::class)
override suspend fun _lowLevelQueryGroupInfo(groupCode: Long): GroupInfo = network.run { override suspend fun _lowLevelQueryGroupInfo(groupCode: Long): GroupInfo = network.run {
TroopManagement.GetGroupInfo( TroopManagement.GetGroupInfo(
client = bot.client, client = bot.client,
...@@ -117,7 +117,7 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -117,7 +117,7 @@ internal abstract class QQAndroidBotBase constructor(
).sendAndExpect<GroupInfoImpl>(retry = 2) ).sendAndExpect<GroupInfoImpl>(retry = 2)
} }
@UseExperimental(LowLevelAPI::class) @OptIn(LowLevelAPI::class)
override suspend fun _lowLevelQueryGroupMemberList( override suspend fun _lowLevelQueryGroupMemberList(
groupUin: Long, groupUin: Long,
groupCode: Long, groupCode: Long,
...@@ -187,7 +187,7 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -187,7 +187,7 @@ internal abstract class QQAndroidBotBase constructor(
} }
} }
@UseExperimental(LowLevelAPI::class) @OptIn(LowLevelAPI::class)
override suspend fun _lowLevelRecallFriendMessage(friendId: Long, messageId: Long, time: Long) { override suspend fun _lowLevelRecallFriendMessage(friendId: Long, messageId: Long, time: Long) {
network.run { network.run {
val response: PbMessageSvc.PbMsgWithDraw.Response = val response: PbMessageSvc.PbMsgWithDraw.Response =
...@@ -198,7 +198,7 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -198,7 +198,7 @@ internal abstract class QQAndroidBotBase constructor(
} }
} }
@UseExperimental(LowLevelAPI::class) @OptIn(LowLevelAPI::class)
override suspend fun _lowLevelRecallGroupMessage(groupId: Long, messageId: Long) { override suspend fun _lowLevelRecallGroupMessage(groupId: Long, messageId: Long) {
network.run { network.run {
val response: PbMessageSvc.PbMsgWithDraw.Response = val response: PbMessageSvc.PbMsgWithDraw.Response =
...@@ -227,5 +227,5 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -227,5 +227,5 @@ internal abstract class QQAndroidBotBase constructor(
} }
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
internal expect fun io.ktor.utils.io.ByteReadChannel.toKotlinByteReadChannel(): ByteReadChannel internal expect fun io.ktor.utils.io.ByteReadChannel.toKotlinByteReadChannel(): ByteReadChannel
\ No newline at end of file
package net.mamoe.mirai.qqandroid.io.serialization
import kotlinx.io.core.Input
import kotlinx.io.core.Output
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerialFormat
import kotlinx.serialization.SerializationStrategy
interface IOFormat : SerialFormat {
fun <T> dumpTo(serializer: SerializationStrategy<T>, ojb: T, output: Output)
fun <T> load(deserializer: DeserializationStrategy<T>, input: Input): T
}
...@@ -5,11 +5,19 @@ ...@@ -5,11 +5,19 @@
* Some code changed by Mamoe is annotated around "MIRAI MODIFY START" and "MIRAI MODIFY END" * Some code changed by Mamoe is annotated around "MIRAI MODIFY START" and "MIRAI MODIFY END"
*/ */
@file:Suppress("DEPRECATION_ERROR")
package net.mamoe.mirai.qqandroid.io.serialization package net.mamoe.mirai.qqandroid.io.serialization
import kotlinx.io.* import kotlinx.io.ByteArrayOutputStream
import kotlinx.io.ByteBuffer
import kotlinx.io.ByteOrder
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.internal.* import kotlinx.serialization.builtins.ByteArraySerializer
import kotlinx.serialization.builtins.MapEntrySerializer
import kotlinx.serialization.builtins.SetSerializer
import kotlinx.serialization.internal.MapLikeSerializer
import kotlinx.serialization.internal.TaggedEncoder
import kotlinx.serialization.modules.EmptyModule import kotlinx.serialization.modules.EmptyModule
import kotlinx.serialization.modules.SerialModule import kotlinx.serialization.modules.SerialModule
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
...@@ -33,15 +41,19 @@ internal fun extractParameters(desc: SerialDescriptor, index: Int, zeroBasedDefa ...@@ -33,15 +41,19 @@ internal fun extractParameters(desc: SerialDescriptor, index: Int, zeroBasedDefa
* *
* 代码复制自 kotlinx.serialization. 修改部分已进行标注 (详见 "MIRAI MODIFY START") * 代码复制自 kotlinx.serialization. 修改部分已进行标注 (详见 "MIRAI MODIFY START")
*/ */
class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : AbstractSerialFormat(context), BinaryFormat { @OptIn(InternalSerializationApi::class)
class ProtoBufWithNullableSupport(override val context: SerialModule = EmptyModule) : SerialFormat, BinaryFormat {
internal open inner class ProtobufWriter(val encoder: ProtobufEncoder) : TaggedEncoder<ProtoDesc>() { internal open inner class ProtobufWriter(private val encoder: ProtobufEncoder) : TaggedEncoder<ProtoDesc>() {
public override val context override val context
get() = this@ProtoBufWithNullableSupport.context get() = this@ProtoBufWithNullableSupport.context
override fun beginStructure(desc: SerialDescriptor, vararg typeParams: KSerializer<*>): CompositeEncoder = when (desc.kind) { override fun beginStructure(
descriptor: SerialDescriptor,
vararg typeSerializers: KSerializer<*>
): CompositeEncoder = when (descriptor.kind) {
StructureKind.LIST -> RepeatedWriter(encoder, currentTag) StructureKind.LIST -> RepeatedWriter(encoder, currentTag)
StructureKind.CLASS, UnionKind.OBJECT, is PolymorphicKind -> ObjectWriter(currentTagOrNull, encoder) StructureKind.CLASS, StructureKind.OBJECT, is PolymorphicKind -> ObjectWriter(currentTagOrNull, encoder)
StructureKind.MAP -> MapRepeatedWriter(currentTagOrNull, encoder) StructureKind.MAP -> MapRepeatedWriter(currentTagOrNull, encoder)
else -> throw SerializationException("Primitives are not supported at top-level") else -> throw SerializationException("Primitives are not supported at top-level")
} }
...@@ -82,12 +94,15 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac ...@@ -82,12 +94,15 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac
@Suppress("UNCHECKED_CAST", "NAME_SHADOWING") @Suppress("UNCHECKED_CAST", "NAME_SHADOWING")
override fun <T> encodeSerializableValue(serializer: SerializationStrategy<T>, value: T) = when { override fun <T> encodeSerializableValue(serializer: SerializationStrategy<T>, value: T) = when {
// encode maps as collection of map entries, not merged collection of key-values // encode maps as collection of map entries, not merged collection of key-values
serializer.descriptor is MapLikeDescriptor -> { serializer.descriptor.kind == StructureKind.MAP -> {
val serializer = (serializer as MapLikeSerializer<Any?, Any?, T, *>) val serializer = (serializer as MapLikeSerializer<Any?, Any?, T, *>)
val mapEntrySerial = MapEntrySerializer(serializer.keySerializer, serializer.valueSerializer) val mapEntrySerial = MapEntrySerializer(serializer.keySerializer, serializer.valueSerializer)
HashSetSerializer(mapEntrySerial).serialize(this, (value as Map<*, *>).entries) SetSerializer(mapEntrySerial).serialize(this, (value as Map<*, *>).entries)
} }
serializer.descriptor == ByteArraySerializer.descriptor -> encoder.writeBytes(value as ByteArray, popTag().first) serializer.descriptor == ByteArraySerializer().descriptor -> encoder.writeBytes(
value as ByteArray,
popTag().first
)
else -> serializer.serialize(this, value) else -> serializer.serialize(this, value)
} }
} }
...@@ -96,7 +111,7 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac ...@@ -96,7 +111,7 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac
val parentTag: ProtoDesc?, private val parentEncoder: ProtobufEncoder, val parentTag: ProtoDesc?, private val parentEncoder: ProtobufEncoder,
private val stream: ByteArrayOutputStream = ByteArrayOutputStream() private val stream: ByteArrayOutputStream = ByteArrayOutputStream()
) : ProtobufWriter(ProtobufEncoder(stream)) { ) : ProtobufWriter(ProtobufEncoder(stream)) {
override fun endEncode(desc: SerialDescriptor) { override fun endEncode(descriptor: SerialDescriptor) {
if (parentTag != null) { if (parentTag != null) {
parentEncoder.writeBytes(stream.toByteArray(), parentTag.first) parentEncoder.writeBytes(stream.toByteArray(), parentTag.first)
} else { } else {
...@@ -111,7 +126,8 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac ...@@ -111,7 +126,8 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac
else 2 to (parentTag?.second ?: ProtoNumberType.DEFAULT) else 2 to (parentTag?.second ?: ProtoNumberType.DEFAULT)
} }
internal inner class RepeatedWriter(encoder: ProtobufEncoder, val curTag: ProtoDesc) : ProtobufWriter(encoder) { internal inner class RepeatedWriter(encoder: ProtobufEncoder, private val curTag: ProtoDesc) :
ProtobufWriter(encoder) {
override fun SerialDescriptor.getTag(index: Int) = curTag override fun SerialDescriptor.getTag(index: Int) = curTag
} }
...@@ -141,8 +157,9 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac ...@@ -141,8 +157,9 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac
out.write(content) out.write(content)
} }
@OptIn(ExperimentalStdlibApi::class)
fun writeString(value: String, tag: Int) { fun writeString(value: String, tag: Int) {
val bytes = value.toUtf8Bytes() val bytes = value.encodeToByteArray()
writeBytes(bytes, tag) writeBytes(bytes, tag)
} }
...@@ -228,17 +245,17 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac ...@@ -228,17 +245,17 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac
internal const val SIZE_DELIMITED = 2 internal const val SIZE_DELIMITED = 2
internal const val i32 = 5 internal const val i32 = 5
val plain = ProtoBufWithNullableSupport() private val plain = ProtoBufWithNullableSupport()
override fun <T> dump(serializer: SerializationStrategy<T>, obj: T): ByteArray = plain.dump(serializer, obj) override fun <T> dump(serializer: SerializationStrategy<T>, value: T): ByteArray = plain.dump(serializer, value)
override fun <T> load(deserializer: DeserializationStrategy<T>, bytes: ByteArray): T = plain.load(deserializer, bytes) override fun <T> load(deserializer: DeserializationStrategy<T>, bytes: ByteArray): T =
override fun install(module: SerialModule) = throw IllegalStateException("You should not install anything to global instance") plain.load(deserializer, bytes)
} }
override fun <T> dump(serializer: SerializationStrategy<T>, obj: T): ByteArray { override fun <T> dump(serializer: SerializationStrategy<T>, value: T): ByteArray {
val encoder = ByteArrayOutputStream() val encoder = ByteArrayOutputStream()
val dumper = ProtobufWriter(ProtobufEncoder(encoder)) val dumper = ProtobufWriter(ProtobufEncoder(encoder))
dumper.encode(serializer, obj) dumper.encode(serializer, value)
return encoder.toByteArray() return encoder.toByteArray()
} }
...@@ -248,20 +265,3 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac ...@@ -248,20 +265,3 @@ class ProtoBufWithNullableSupport(context: SerialModule = EmptyModule) : Abstrac
} }
internal fun InputStream.readExactNBytes(bytes: Int): ByteArray {
val array = ByteArray(bytes)
var read = 0
while (read < bytes) {
val i = this.read(array, read, bytes - read)
if (i == -1) throw IOException("Unexpected EOF")
read += i
}
return array
}
internal fun InputStream.readToByteBuffer(bytes: Int): ByteBuffer {
val arr = readExactNBytes(bytes)
val buf = ByteBuffer.allocate(bytes)
buf.put(arr).flip()
return buf
}
\ No newline at end of file
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.qqandroid.io.serialization.jce
import kotlinx.io.core.*
import net.mamoe.mirai.qqandroid.io.serialization.JceCharset
import net.mamoe.mirai.utils.io.readString
/**
* Jce Input. 需要手动管理 head.
*/
internal class JceInput(
val input: Input, val charset: JceCharset
) {
private var _head: JceHead? = null
val currentHead: JceHead get() = _head ?: throw EOFException("No current JceHead available")
val currentHeadOrNull: JceHead? get() = _head
init {
prepareNextHead()
}
/**
* 读取下一个 [JceHead] 并保存. 可通过 [currentHead] 获取这个 [JceHead].
*
* @return 是否成功读取. 返回 `false` 时代表 [Input.endOfInput]
*/
fun prepareNextHead(): Boolean {
return readNextHeadButDoNotAssignTo_Head().also { _head = it; } != null
}
fun nextHead(): JceHead {
if (!prepareNextHead()) {
throw EOFException("No more JceHead available")
}
return currentHead
}
/**
* 直接读取下一个 [JceHead] 并返回.
* 返回 `null` 则代表 [Input.endOfInput]
*/
@Suppress("FunctionName")
@OptIn(ExperimentalUnsignedTypes::class)
private fun readNextHeadButDoNotAssignTo_Head(): JceHead? {
if (input.endOfInput) {
return null
}
val var2 = input.readUByte()
val type = var2 and 15u
var tag = var2.toUInt() shr 4
if (tag == 15u) {
tag = input.readUByte().toUInt()
}
return JceHead(
tag = tag.toInt(),
type = type.toByte()
)
}
/**
* 使用这个 [JceHead].
* [block] 结束后将会 [准备下一个 [JceHead]][prepareNextHead]
*/
inline fun <R> useHead(crossinline block: (JceHead) -> R): R {
return currentHead.let(block).also { prepareNextHead() }
}
/**
* 跳过 [JceHead] 和对应的数据值, 直到找到 [tag], 否则返回 `null`
*/
inline fun <R> skipToHeadAndUseIfPossibleOrNull(tag: Int, crossinline block: (JceHead) -> R): R? {
return skipToHeadOrNull(tag)?.let(block).also { prepareNextHead() }
}
/**
* 跳过 [JceHead] 和对应的数据值, 直到找到 [tag], 否则抛出异常
*/
inline fun <R : Any> skipToHeadAndUseIfPossibleOrFail(
tag: Int,
crossinline message: () -> String = { "tag not found: $tag" },
crossinline block: (JceHead) -> R
): R {
return checkNotNull<R>(skipToHeadAndUseIfPossibleOrNull(tag, block), message)
}
tailrec fun skipToHeadOrNull(tag: Int): JceHead? {
val current: JceHead = currentHeadOrNull ?: return null // no backing field
return when {
current.tag > tag -> null // tag 大了,即找不到
current.tag == tag -> current // 满足需要.
else -> { // tag 小了
skipField(current.type)
check(prepareNextHead()) { "cannot skip to tag $tag, early EOF" }
skipToHeadOrNull(tag)
}
}
}
inline fun skipToHeadOrFail(
tag: Int,
message: () -> String = { "head not found: $tag" }
): JceHead {
return checkNotNull(skipToHeadOrNull(tag), message)
}
@OptIn(ExperimentalUnsignedTypes::class)
@PublishedApi
internal fun skipField(type: Byte): Unit = when (type) {
Jce.BYTE -> this.input.discardExact(1)
Jce.SHORT -> this.input.discardExact(2)
Jce.INT -> this.input.discardExact(4)
Jce.LONG -> this.input.discardExact(8)
Jce.FLOAT -> this.input.discardExact(4)
Jce.DOUBLE -> this.input.discardExact(8)
Jce.STRING1 -> this.input.discardExact(this.input.readUByte().toInt())
Jce.STRING4 -> this.input.discardExact(this.input.readInt())
Jce.MAP -> { // map
repeat(skipToHeadAndUseIfPossibleOrFail(0) {
readJceIntValue(it)
} * 2) {
useHead { skipField(it.type) }
}
}
Jce.LIST -> { // list
repeat(skipToHeadAndUseIfPossibleOrFail(0) {
readJceIntValue(it)
}) {
useHead { skipField(it.type) }
}
}
Jce.STRUCT_BEGIN -> {
fun skipToStructEnd() {
var head: JceHead
do {
head = nextHead()
skipField(head.type)
} while (head.type.toInt() != 11)
}
skipToStructEnd()
}
Jce.STRUCT_END, Jce.ZERO_TYPE -> {
}
Jce.SIMPLE_LIST -> {
val head = nextHead()
check(head.type.toInt() == 0) { "skipField with invalid type, type value: " + type + ", " + head.type }
this.input.discardExact(
skipToHeadAndUseIfPossibleOrFail(0) {
readJceIntValue(it)
}
)
}
else -> error("invalid type: $type")
}
// region readers
fun readJceIntValue(head: JceHead): Int {
//println("readJceIntValue: $head")
return when (head.type) {
Jce.ZERO_TYPE -> 0
Jce.BYTE -> input.readByte().toInt()
Jce.SHORT -> input.readShort().toInt()
Jce.INT -> input.readInt()
else -> error("type mismatch: ${head.type}")
}
}
fun readJceShortValue(head: JceHead): Short {
return when (head.type) {
Jce.ZERO_TYPE -> 0
Jce.BYTE -> input.readByte().toShort()
Jce.SHORT -> input.readShort()
else -> error("type mismatch: ${head.type}")
}
}
fun readJceLongValue(head: JceHead): Long {
return when (head.type) {
Jce.ZERO_TYPE -> 0
Jce.BYTE -> input.readByte().toLong()
Jce.SHORT -> input.readShort().toLong()
Jce.INT -> input.readInt().toLong()
Jce.LONG -> input.readLong()
else -> error("type mismatch ${head.type}")
}
}
fun readJceByteValue(head: JceHead): Byte {
//println("readJceByteValue: $head")
return when (head.type) {
Jce.ZERO_TYPE -> 0
Jce.BYTE -> input.readByte()
else -> error("type mismatch: ${head.type}")
}
}
fun readJceFloatValue(head: JceHead): Float {
return when (head.type) {
Jce.ZERO_TYPE -> 0f
Jce.FLOAT -> input.readFloat()
else -> error("type mismatch: ${head.type}")
}
}
@OptIn(ExperimentalUnsignedTypes::class)
fun readJceStringValue(head: JceHead): String {
//println("readJceStringValue: $head")
return when (head.type) {
Jce.STRING1 -> input.readString(input.readUByte().toInt(), charset = charset.kotlinCharset)
Jce.STRING4 -> input.readString(
input.readUInt().toInt().also { require(it in 1 until 104857600) { "bad string length: $it" } },
charset = charset.kotlinCharset
)
else -> error("type mismatch: ${head.type}, expecting 6 or 7 (for string)")
}
}
fun readJceDoubleValue(head: JceHead): Double {
return when (head.type.toInt()) {
12 -> 0.0
4 -> input.readFloat().toDouble()
5 -> input.readDouble()
else -> error("type mismatch: ${head.type}")
}
}
fun readJceBooleanValue(head: JceHead): Boolean {
return readJceByteValue(head) == 1.toByte()
}
}
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.qqandroid.io.serialization.jce
import kotlinx.io.core.*
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerialFormat
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.modules.EmptyModule
import kotlinx.serialization.modules.SerialModule
import net.mamoe.mirai.qqandroid.io.serialization.IOFormat
import net.mamoe.mirai.qqandroid.io.serialization.JceCharset
import net.mamoe.mirai.qqandroid.io.serialization.JceOld
import net.mamoe.mirai.utils.io.toReadPacket
/**
* Jce 数据结构序列化和反序列化器.
*
* @author Him188
*/
class Jce(
override val context: SerialModule,
val charset: JceCharset
) : SerialFormat, IOFormat, BinaryFormat {
override fun <T> dumpTo(serializer: SerializationStrategy<T>, ojb: T, output: Output) {
output.writePacket(JceOld.byCharSet(this.charset).dumpAsPacket(serializer, ojb))
}
override fun <T> load(deserializer: DeserializationStrategy<T>, input: Input): T {
return JceDecoder(JceInput(input, charset), context).decodeSerializableValue(deserializer)
}
override fun <T> dump(serializer: SerializationStrategy<T>, value: T): ByteArray {
return buildPacket { dumpTo(serializer, value, this) }.readBytes()
}
override fun <T> load(deserializer: DeserializationStrategy<T>, bytes: ByteArray): T {
return load(deserializer, bytes.toReadPacket())
}
companion object {
val UTF_8 = Jce(EmptyModule, JceCharset.UTF8)
val GBK = Jce(EmptyModule, JceCharset.GBK)
fun byCharSet(c: JceCharset): Jce {
return if (c == JceCharset.UTF8) UTF_8 else GBK
}
internal const val BYTE: Byte = 0
internal const val DOUBLE: Byte = 5
internal const val FLOAT: Byte = 4
internal const val INT: Byte = 2
internal const val JCE_MAX_STRING_LENGTH = 104857600
internal const val LIST: Byte = 9
internal const val LONG: Byte = 3
internal const val MAP: Byte = 8
internal const val SHORT: Byte = 1
internal const val SIMPLE_LIST: Byte = 13
internal const val STRING1: Byte = 6
internal const val STRING4: Byte = 7
internal const val STRUCT_BEGIN: Byte = 10
internal const val STRUCT_END: Byte = 11
internal const val ZERO_TYPE: Byte = 12
}
}
\ No newline at end of file
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.qqandroid.io.serialization.jce
import kotlinx.io.core.Output
import kotlinx.serialization.SerialInfo
/**
* 标注 JCE 序列化时使用的 ID
*/
@SerialInfo
@Target(AnnotationTarget.PROPERTY)
annotation class JceId(val id: Int)
/**
* 类中元素的 tag
*
* 保留这个结构, 为将来增加功能的兼容性.
*/
@PublishedApi
internal abstract class JceTag {
abstract val id: Int
internal var isSimpleByteArray: Boolean = false
}
internal object JceTagListElement : JceTag() {
override val id: Int get() = 0
override fun toString(): String {
return "JceTagListElement"
}
}
internal object JceTagMapEntryKey : JceTag() {
override val id: Int get() = 0
override fun toString(): String {
return "JceTagMapEntryKey"
}
}
internal object JceTagMapEntryValue : JceTag() {
override val id: Int get() = 1
override fun toString(): String {
return "JceTagMapEntryValue"
}
}
internal data class JceTagCommon(
override val id: Int
) : JceTag()
fun JceHead.checkType(type: Byte) {
check(this.type == type) { "type mismatch. Expected $type, actual ${this.type}" }
}
@PublishedApi
internal fun Output.writeJceHead(type: Byte, tag: Int) {
if (tag < 15) {
writeByte(((tag shl 4) or type.toInt()).toByte())
return
}
if (tag < 256) {
writeByte((type.toInt() or 0xF0).toByte())
writeByte(tag.toByte())
return
}
error("tag is too large: $tag")
}
@OptIn(ExperimentalUnsignedTypes::class)
inline class JceHead(private val value: Long) {
constructor(tag: Int, type: Byte) : this(tag.toLong().shl(32) or type.toLong())
val tag: Int get() = (value ushr 32).toInt()
val type: Byte get() = value.toUInt().toByte()
override fun toString(): String {
val typeString = when (type) {
Jce.BYTE -> "Byte"
Jce.DOUBLE -> "Double"
Jce.FLOAT -> "Float"
Jce.INT -> "Int"
Jce.LIST -> "List"
Jce.LONG -> "Long"
Jce.MAP -> "Map"
Jce.SHORT -> "Short"
Jce.SIMPLE_LIST -> "SimpleList"
Jce.STRING1 -> "String1"
Jce.STRING4 -> "String4"
Jce.STRUCT_BEGIN -> "StructBegin"
Jce.STRUCT_END -> "StructEnd"
Jce.ZERO_TYPE -> "Zero"
else -> error("illegal jce type: $type")
}
return "JceHead(tag=$tag, type=$type($typeString))"
}
}
\ No newline at end of file
...@@ -18,21 +18,29 @@ import kotlinx.serialization.SerialDescriptor ...@@ -18,21 +18,29 @@ import kotlinx.serialization.SerialDescriptor
import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.SerializationStrategy
import net.mamoe.mirai.qqandroid.io.JceStruct import net.mamoe.mirai.qqandroid.io.JceStruct
import net.mamoe.mirai.qqandroid.io.ProtoBuf import net.mamoe.mirai.qqandroid.io.ProtoBuf
import net.mamoe.mirai.qqandroid.io.serialization.jce.Jce
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataVersion2 import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataVersion2
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataVersion3 import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestDataVersion3
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.firstValue import net.mamoe.mirai.utils.firstValue
import net.mamoe.mirai.utils.io.read import net.mamoe.mirai.utils.io.read
import net.mamoe.mirai.utils.io.readPacketExact
import net.mamoe.mirai.utils.io.toReadPacket
import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
fun <T : JceStruct> ByteArray.loadAs(deserializer: DeserializationStrategy<T>, c: JceCharset = JceCharset.UTF8): T { fun <T : JceStruct> ByteArray.loadAs(deserializer: DeserializationStrategy<T>, c: JceCharset = JceCharset.UTF8): T {
return Jce.byCharSet(c).load(deserializer, this) return Jce.byCharSet(c).load(deserializer, this.toReadPacket())
} }
fun <T : JceStruct> BytePacketBuilder.writeJceStruct(serializer: SerializationStrategy<T>, struct: T, charset: JceCharset = JceCharset.GBK) { fun <T : JceStruct> BytePacketBuilder.writeJceStruct(
this.writePacket(Jce.byCharSet(charset).dumpAsPacket(serializer, struct)) serializer: SerializationStrategy<T>,
struct: T,
charset: JceCharset = JceCharset.GBK
) {
Jce.byCharSet(charset).dumpTo(serializer, struct, this)
} }
fun <T : JceStruct> ByteReadPacket.readJceStruct( fun <T : JceStruct> ByteReadPacket.readJceStruct(
...@@ -40,7 +48,8 @@ fun <T : JceStruct> ByteReadPacket.readJceStruct( ...@@ -40,7 +48,8 @@ fun <T : JceStruct> ByteReadPacket.readJceStruct(
charset: JceCharset = JceCharset.UTF8, charset: JceCharset = JceCharset.UTF8,
length: Int = this.remaining.toInt() length: Int = this.remaining.toInt()
): T { ): T {
return Jce.byCharSet(charset).load(serializer, this, length) @OptIn(MiraiInternalAPI::class)
return Jce.byCharSet(charset).load(serializer, this.readPacketExact(length))
} }
/** /**
...@@ -70,18 +79,20 @@ fun <T : ProtoBuf> ByteReadPacket.decodeUniPacket(deserializer: DeserializationS ...@@ -70,18 +79,20 @@ fun <T : ProtoBuf> ByteReadPacket.decodeUniPacket(deserializer: DeserializationS
fun <R> ByteReadPacket.decodeUniRequestPacketAndDeserialize(name: String? = null, block: (ByteArray) -> R): R { fun <R> ByteReadPacket.decodeUniRequestPacketAndDeserialize(name: String? = null, block: (ByteArray) -> R): R {
val request = this.readJceStruct(RequestPacket.serializer()) val request = this.readJceStruct(RequestPacket.serializer())
return block(if (name == null) when (request.iVersion.toInt()) { return block(if (name == null) when (request.iVersion?.toInt() ?: 3) {
2 -> request.sBuffer.loadAs(RequestDataVersion2.serializer()).map.firstValue().firstValue() 2 -> request.sBuffer.loadAs(RequestDataVersion2.serializer()).map.firstValue().firstValue()
3 -> request.sBuffer.loadAs(RequestDataVersion3.serializer()).map.firstValue() 3 -> request.sBuffer.loadAs(RequestDataVersion3.serializer()).map.firstValue()
else -> error("unsupported version ${request.iVersion}") else -> error("unsupported version ${request.iVersion}")
} else when (request.iVersion.toInt()) { } else when (request.iVersion?.toInt() ?: 3) {
2 -> request.sBuffer.loadAs(RequestDataVersion2.serializer()).map.getOrElse(name) { error("cannot find $name") }.firstValue() 2 -> request.sBuffer.loadAs(RequestDataVersion2.serializer()).map.getOrElse(name) { error("cannot find $name") }
.firstValue()
3 -> request.sBuffer.loadAs(RequestDataVersion3.serializer()).map.getOrElse(name) { error("cannot find $name") } 3 -> request.sBuffer.loadAs(RequestDataVersion3.serializer()).map.getOrElse(name) { error("cannot find $name") }
else -> error("unsupported version ${request.iVersion}") else -> error("unsupported version ${request.iVersion}")
}) })
} }
fun <T : JceStruct> T.toByteArray(serializer: SerializationStrategy<T>, c: JceCharset = JceCharset.GBK): ByteArray = Jce.byCharSet(c).dump(serializer, this) fun <T : JceStruct> T.toByteArray(serializer: SerializationStrategy<T>, c: JceCharset = JceCharset.GBK): ByteArray =
Jce.byCharSet(c).dump(serializer, this)
fun <T : ProtoBuf> BytePacketBuilder.writeProtoBuf(serializer: SerializationStrategy<T>, v: T) { fun <T : ProtoBuf> BytePacketBuilder.writeProtoBuf(serializer: SerializationStrategy<T>, v: T) {
this.writeFully(v.toByteArray(serializer)) this.writeFully(v.toByteArray(serializer))
......
...@@ -253,7 +253,7 @@ internal class MessageSourceFromSendFriend( ...@@ -253,7 +253,7 @@ internal class MessageSourceFromSendFriend(
val sequenceId: Int, val sequenceId: Int,
override val originalMessage: MessageChain override val originalMessage: MessageChain
) : MessageSourceFromSend() { ) : MessageSourceFromSend() {
@UseExperimental(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
override val id: Long override val id: Long
get() = sequenceId.toLong().shl(32) or get() = sequenceId.toLong().shl(32) or
messageRandom.toLong().and(0xFFFFFFFF) messageRandom.toLong().and(0xFFFFFFFF)
...@@ -277,12 +277,12 @@ internal class MessageSourceFromSendGroup( ...@@ -277,12 +277,12 @@ internal class MessageSourceFromSendGroup(
) : MessageSourceFromSend() { ) : MessageSourceFromSend() {
private lateinit var sequenceIdDeferred: Deferred<Int> private lateinit var sequenceIdDeferred: Deferred<Int>
@UseExperimental(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
override val id: Long override val id: Long
get() = sequenceIdDeferred.getCompleted().toLong().shl(32) or get() = sequenceIdDeferred.getCompleted().toLong().shl(32) or
messageRandom.toLong().and(0xFFFFFFFF) messageRandom.toLong().and(0xFFFFFFFF)
@UseExperimental(MiraiExperimentalAPI::class) @OptIn(MiraiExperimentalAPI::class)
internal fun startWaitingSequenceId(coroutineScope: CoroutineScope) { internal fun startWaitingSequenceId(coroutineScope: CoroutineScope) {
sequenceIdDeferred = sequenceIdDeferred =
coroutineScope.subscribingGetAsync<OnlinePush.PbPushGroupMsg.SendGroupMessageReceipt, Int>( coroutineScope.subscribingGetAsync<OnlinePush.PbPushGroupMsg.SendGroupMessageReceipt, Int>(
......
...@@ -222,7 +222,7 @@ private val atAllData = ImMsgBody.Elem( ...@@ -222,7 +222,7 @@ private val atAllData = ImMsgBody.Elem(
) )
) )
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
internal fun MessageChain.toRichTextElems(forGroup: Boolean): MutableList<ImMsgBody.Elem> { internal fun MessageChain.toRichTextElems(forGroup: Boolean): MutableList<ImMsgBody.Elem> {
val elements = mutableListOf<ImMsgBody.Elem>() val elements = mutableListOf<ImMsgBody.Elem>()
...@@ -335,7 +335,7 @@ internal class OnlineFriendImageImpl( ...@@ -335,7 +335,7 @@ internal class OnlineFriendImageImpl(
} }
} }
@UseExperimental(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class) @OptIn(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class)
internal fun MsgComm.Msg.toMessageChain(): MessageChain { internal fun MsgComm.Msg.toMessageChain(): MessageChain {
val elements = this.msgBody.richText.elems val elements = this.msgBody.richText.elems
...@@ -346,7 +346,7 @@ internal fun MsgComm.Msg.toMessageChain(): MessageChain { ...@@ -346,7 +346,7 @@ internal fun MsgComm.Msg.toMessageChain(): MessageChain {
} }
// These two functions are not identical, dont combine. // These two functions are not identical, dont combine.
@UseExperimental(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class) @OptIn(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class)
internal fun ImMsgBody.SourceMsg.toMessageChain(): MessageChain { internal fun ImMsgBody.SourceMsg.toMessageChain(): MessageChain {
val elements = this.elems!! val elements = this.elems!!
...@@ -371,7 +371,9 @@ private fun MessageChain.removeAtIfHasQuoteReply(): MessageChain = ...@@ -371,7 +371,9 @@ private fun MessageChain.removeAtIfHasQuoteReply(): MessageChain =
}.asMessageChain() }.asMessageChain()
} else this*/ } else this*/
@UseExperimental(MiraiInternalAPI::class, ExperimentalUnsignedTypes::class, MiraiDebugAPI::class, LowLevelAPI::class) @OptIn(
MiraiInternalAPI::class, ExperimentalUnsignedTypes::class, MiraiDebugAPI::class, LowLevelAPI::class
)
internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MessageChainBuilder) { internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MessageChainBuilder) {
this.forEach { this.forEach {
when { when {
......
...@@ -48,7 +48,7 @@ import kotlin.jvm.Volatile ...@@ -48,7 +48,7 @@ import kotlin.jvm.Volatile
import kotlin.time.ExperimentalTime import kotlin.time.ExperimentalTime
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler() { internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler() {
override val bot: QQAndroidBot by bot.unsafeWeakRef() override val bot: QQAndroidBot by bot.unsafeWeakRef()
override val supervisor: CompletableJob = SupervisorJob(bot.coroutineContext[Job]) override val supervisor: CompletableJob = SupervisorJob(bot.coroutineContext[Job])
...@@ -183,7 +183,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler ...@@ -183,7 +183,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
internal var pendingIncomingPackets: LockFreeLinkedList<KnownPacketFactories.IncomingPacket<*>>? = internal var pendingIncomingPackets: LockFreeLinkedList<KnownPacketFactories.IncomingPacket<*>>? =
LockFreeLinkedList() LockFreeLinkedList()
@UseExperimental(MiraiExperimentalAPI::class, ExperimentalTime::class) @OptIn(MiraiExperimentalAPI::class, ExperimentalTime::class)
override suspend fun init(): Unit = coroutineScope { override suspend fun init(): Unit = coroutineScope {
check(bot.isActive) { "bot is dead therefore network can't init" } check(bot.isActive) { "bot is dead therefore network can't init" }
check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't init" } check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't init" }
...@@ -380,10 +380,17 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler ...@@ -380,10 +380,17 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
* *
* @param input 一个完整的包的内容, 去掉开头的 int 包长度 * @param input 一个完整的包的内容, 去掉开头的 int 包长度
*/ */
@UseExperimental(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
fun parsePacketAsync(input: Input): Job { fun parsePacketAsync(input: Input): Job {
return this.launch(start = CoroutineStart.ATOMIC) { return this.launch(
input.use { parsePacket(it) } start = CoroutineStart.ATOMIC
) {
try {
input.use { parsePacket(it) }
} catch (e: Exception) {
// 傻逼协程吞异常
logger.error(e)
}
} }
} }
......
...@@ -40,7 +40,7 @@ import net.mamoe.mirai.utils.io.* ...@@ -40,7 +40,7 @@ import net.mamoe.mirai.utils.io.*
DOMAINS DOMAINS
Pskey: "openmobile.qq.com" Pskey: "openmobile.qq.com"
*/ */
@UseExperimental(MiraiExperimentalAPI::class, MiraiInternalAPI::class) @OptIn(MiraiExperimentalAPI::class, MiraiInternalAPI::class)
@PublishedApi @PublishedApi
internal open class QQAndroidClient( internal open class QQAndroidClient(
context: Context, context: Context,
...@@ -158,7 +158,7 @@ internal open class QQAndroidClient( ...@@ -158,7 +158,7 @@ internal open class QQAndroidClient(
*/ */
val uin: Long get() = _uin val uin: Long get() = _uin
@UseExperimental(RawAccountIdUse::class) @OptIn(RawAccountIdUse::class)
@Suppress("PropertyName", "DEPRECATION_ERROR") @Suppress("PropertyName", "DEPRECATION_ERROR")
internal var _uin: Long = bot.account.id internal var _uin: Long = bot.account.id
......
...@@ -34,8 +34,9 @@ import net.mamoe.mirai.utils.copyAndClose ...@@ -34,8 +34,9 @@ import net.mamoe.mirai.utils.copyAndClose
import net.mamoe.mirai.utils.io.ByteArrayPool import net.mamoe.mirai.utils.io.ByteArrayPool
import net.mamoe.mirai.utils.io.PlatformSocket import net.mamoe.mirai.utils.io.PlatformSocket
import net.mamoe.mirai.utils.io.withUse import net.mamoe.mirai.utils.io.withUse
import kotlinx.serialization.InternalSerializationApi
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class, InternalSerializationApi::class)
@Suppress("SpellCheckingInspection") @Suppress("SpellCheckingInspection")
internal suspend fun HttpClient.postImage( internal suspend fun HttpClient.postImage(
htcmd: String, htcmd: String,
...@@ -93,9 +94,9 @@ internal suspend fun HttpClient.postImage( ...@@ -93,9 +94,9 @@ internal suspend fun HttpClient.postImage(
} }
} == HttpStatusCode.OK } == HttpStatusCode.OK
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class, InternalSerializationApi::class)
internal object HighwayHelper { internal object HighwayHelper {
@UseExperimental(InternalCoroutinesApi::class) @OptIn(InternalCoroutinesApi::class)
suspend fun uploadImage( suspend fun uploadImage(
client: QQAndroidClient, client: QQAndroidClient,
serverIp: String, serverIp: String,
......
...@@ -25,8 +25,9 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.CSDataHighwayHead ...@@ -25,8 +25,9 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.CSDataHighwayHead
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
import kotlinx.serialization.InternalSerializationApi
@UseExperimental(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class, InternalSerializationApi::class)
internal fun createImageDataPacketSequence( // RequestDataTrans internal fun createImageDataPacketSequence( // RequestDataTrans
client: QQAndroidClient, client: QQAndroidClient,
command: String, command: String,
......
...@@ -9,139 +9,139 @@ ...@@ -9,139 +9,139 @@
package net.mamoe.mirai.qqandroid.network.protocol.data.jce package net.mamoe.mirai.qqandroid.network.protocol.data.jce
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.qqandroid.io.JceStruct import net.mamoe.mirai.qqandroid.io.JceStruct
import net.mamoe.mirai.qqandroid.io.serialization.jce.JceId
@Serializable @Serializable
internal class BigDataChannel( internal class BigDataChannel(
@SerialId(0) val vBigdataIplists: List<BigDataIpList>, @JceId(0) val vBigdataIplists: List<BigDataIpList>,
@SerialId(1) val sBigdataSigSession: ByteArray? = null, @JceId(1) val sBigdataSigSession: ByteArray? = null,
@SerialId(2) val sBigdataKeySession: ByteArray? = null, @JceId(2) val sBigdataKeySession: ByteArray? = null,
@SerialId(3) val uSigUin: Long? = null, @JceId(3) val uSigUin: Long? = null,
@SerialId(4) val iConnectFlag: Int? = 1, @JceId(4) val iConnectFlag: Int? = 1,
@SerialId(5) val vBigdataPbBuf: ByteArray? = null @JceId(5) val vBigdataPbBuf: ByteArray? = null
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class BigDataIpInfo( internal class BigDataIpInfo(
@SerialId(0) val uType: Long, @JceId(0) val uType: Long,
@SerialId(1) val sIp: String = "", @JceId(1) val sIp: String = "",
@SerialId(2) val uPort: Long @JceId(2) val uPort: Long
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class BigDataIpList( internal class BigDataIpList(
@SerialId(0) val uServiceType: Long, @JceId(0) val uServiceType: Long,
@SerialId(1) val vIplist: List<BigDataIpInfo>, @JceId(1) val vIplist: List<BigDataIpInfo>,
@SerialId(2) val netSegConfs: List<NetSegConf>? = null, @JceId(2) val netSegConfs: List<NetSegConf>? = null,
@SerialId(3) val ufragmentSize: Long? = null @JceId(3) val ufragmentSize: Long? = null
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class ClientLogConfig( internal class ClientLogConfig(
@SerialId(1) val type: Int, @JceId(1) val type: Int,
@SerialId(2) val timeStart: TimeStamp? = null, @JceId(2) val timeStart: TimeStamp? = null,
@SerialId(3) val timeFinish: TimeStamp? = null, @JceId(3) val timeFinish: TimeStamp? = null,
@SerialId(4) val loglevel: Byte? = null, @JceId(4) val loglevel: Byte? = null,
@SerialId(5) val cookie: Int? = null, @JceId(5) val cookie: Int? = null,
@SerialId(6) val lseq: Long? = null @JceId(6) val lseq: Long? = null
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class DomainIpChannel( internal class DomainIpChannel(
@SerialId(0) val vDomainIplists: List<DomainIpList> @JceId(0) val vDomainIplists: List<DomainIpList>
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class DomainIpInfo( internal class DomainIpInfo(
@SerialId(1) val uIp: Int, @JceId(1) val uIp: Int,
@SerialId(2) val uPort: Int @JceId(2) val uPort: Int
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class DomainIpList( internal class DomainIpList(
@SerialId(0) val uDomainType: Int, @JceId(0) val uDomainType: Int,
@SerialId(1) val vIplist: List<DomainIpInfo> @JceId(1) val vIplist: List<DomainIpInfo>
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class FileStoragePushFSSvcList( internal class FileStoragePushFSSvcList(
@SerialId(0) val vUpLoadList: List<FileStorageServerListInfo>, @JceId(0) val vUpLoadList: List<FileStorageServerListInfo>,
@SerialId(1) val vPicDownLoadList: List<FileStorageServerListInfo>, @JceId(1) val vPicDownLoadList: List<FileStorageServerListInfo>,
@SerialId(2) val vGPicDownLoadList: List<FileStorageServerListInfo>? = null, @JceId(2) val vGPicDownLoadList: List<FileStorageServerListInfo>? = null,
@SerialId(3) val vQzoneProxyServiceList: List<FileStorageServerListInfo>? = null, @JceId(3) val vQzoneProxyServiceList: List<FileStorageServerListInfo>? = null,
@SerialId(4) val vUrlEncodeServiceList: List<FileStorageServerListInfo>? = null, @JceId(4) val vUrlEncodeServiceList: List<FileStorageServerListInfo>? = null,
@SerialId(5) val bigDataChannel: BigDataChannel? = null, @JceId(5) val bigDataChannel: BigDataChannel? = null,
@SerialId(6) val vVipEmotionList: List<FileStorageServerListInfo>? = null, @JceId(6) val vVipEmotionList: List<FileStorageServerListInfo>? = null,
@SerialId(7) val vC2CPicDownList: List<FileStorageServerListInfo>? = null, @JceId(7) val vC2CPicDownList: List<FileStorageServerListInfo>? = null,
@SerialId(8) val fmtIPInfo: FmtIPInfo? = null, @JceId(8) val fmtIPInfo: FmtIPInfo? = null,
@SerialId(9) val domainIpChannel: DomainIpChannel? = null, @JceId(9) val domainIpChannel: DomainIpChannel? = null,
@SerialId(10) val pttlist: ByteArray? = null @JceId(10) val pttlist: ByteArray? = null
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class FileStorageServerListInfo( internal class FileStorageServerListInfo(
@SerialId(1) val sIP: String = "", @JceId(1) val sIP: String = "",
@SerialId(2) val iPort: Int @JceId(2) val iPort: Int
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class FmtIPInfo( internal class FmtIPInfo(
@SerialId(0) val sGateIp: String = "", @JceId(0) val sGateIp: String = "",
@SerialId(1) val iGateIpOper: Long @JceId(1) val iGateIpOper: Long
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class NetSegConf( internal class NetSegConf(
@SerialId(0) val uint32NetType: Long? = null, @JceId(0) val uint32NetType: Long? = null,
@SerialId(1) val uint32Segsize: Long? = null, @JceId(1) val uint32Segsize: Long? = null,
@SerialId(2) val uint32Segnum: Long? = null, @JceId(2) val uint32Segnum: Long? = null,
@SerialId(3) val uint32Curconnnum: Long? = null @JceId(3) val uint32Curconnnum: Long? = null
) : JceStruct ) : JceStruct
@Suppress("ArrayInDataClass") @Suppress("ArrayInDataClass")
@Serializable @Serializable
internal data class PushReq( internal data class PushReq(
@SerialId(1) val type: Int, @JceId(1) val type: Int,
@SerialId(2) val jcebuf: ByteArray, @JceId(2) val jcebuf: ByteArray,
@SerialId(3) val seq: Long @JceId(3) val seq: Long
) : JceStruct, Packet ) : JceStruct, Packet
@Serializable @Serializable
internal class PushResp( internal class PushResp(
@SerialId(1) val type: Int, @JceId(1) val type: Int,
@SerialId(2) val seq: Long, @JceId(2) val seq: Long,
@SerialId(3) val jcebuf: ByteArray? = null @JceId(3) val jcebuf: ByteArray? = null
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class SsoServerList( internal class SsoServerList(
@SerialId(1) val v2G3GList: List<SsoServerListInfo>, @JceId(1) val v2G3GList: List<SsoServerListInfo>,
@SerialId(3) val vWifiList: List<SsoServerListInfo>, @JceId(3) val vWifiList: List<SsoServerListInfo>,
@SerialId(4) val iReconnect: Int, @JceId(4) val iReconnect: Int,
@SerialId(5) val testSpeed: Byte? = null, @JceId(5) val testSpeed: Byte? = null,
@SerialId(6) val useNewList: Byte? = null, @JceId(6) val useNewList: Byte? = null,
@SerialId(7) val iMultiConn: Int? = 1, @JceId(7) val iMultiConn: Int? = 1,
@SerialId(8) val vHttp2g3glist: List<SsoServerListInfo>? = null, @JceId(8) val vHttp2g3glist: List<SsoServerListInfo>? = null,
@SerialId(9) val vHttpWifilist: List<SsoServerListInfo>? = null @JceId(9) val vHttpWifilist: List<SsoServerListInfo>? = null
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class SsoServerListInfo( internal class SsoServerListInfo(
@SerialId(1) val sIP: String = "", @JceId(1) val sIP: String = "",
@SerialId(2) val iPort: Int, @JceId(2) val iPort: Int,
@SerialId(3) val linkType: Byte, @JceId(3) val linkType: Byte,
@SerialId(4) val proxy: Byte, @JceId(4) val proxy: Byte,
@SerialId(5) val protocolType: Byte? = null, @JceId(5) val protocolType: Byte? = null,
@SerialId(6) val iTimeOut: Int? = 10 @JceId(6) val iTimeOut: Int? = 10
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class TimeStamp( internal class TimeStamp(
@SerialId(1) val year: Int, @JceId(1) val year: Int,
@SerialId(2) val month: Byte, @JceId(2) val month: Byte,
@SerialId(3) val day: Byte, @JceId(3) val day: Byte,
@SerialId(4) val hour: Byte @JceId(4) val hour: Byte
) : JceStruct ) : JceStruct
...@@ -9,72 +9,72 @@ ...@@ -9,72 +9,72 @@
package net.mamoe.mirai.qqandroid.network.protocol.data.jce package net.mamoe.mirai.qqandroid.network.protocol.data.jce
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.qqandroid.io.JceStruct import net.mamoe.mirai.qqandroid.io.JceStruct
import net.mamoe.mirai.qqandroid.io.serialization.jce.JceId
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
@Suppress("ArrayInDataClass") @Suppress("ArrayInDataClass")
@Serializable @Serializable
internal data class RequestPushNotify( internal data class RequestPushNotify(
@SerialId(0) val uin: Long? = 0L, @JceId(0) val uin: Long? = 0L,
@SerialId(1) val ctype: Byte = 0, @JceId(1) val ctype: Byte = 0,
@SerialId(2) val strService: String?, @JceId(2) val strService: String?,
@SerialId(3) val strCmd: String?, @JceId(3) val strCmd: String?,
@SerialId(4) val vNotifyCookie: ByteArray? = EMPTY_BYTE_ARRAY, @JceId(4) val vNotifyCookie: ByteArray? = EMPTY_BYTE_ARRAY,
@SerialId(5) val usMsgType: Int?, @JceId(5) val usMsgType: Int?,
@SerialId(6) val wUserActive: Int?, @JceId(6) val wUserActive: Int?,
@SerialId(7) val wGeneralFlag: Int?, @JceId(7) val wGeneralFlag: Int?,
@SerialId(8) val bindedUin: Long?, @JceId(8) val bindedUin: Long?,
@SerialId(9) val stMsgInfo: MsgInfo?, @JceId(9) val stMsgInfo: MsgInfo?,
@SerialId(10) val msgCtrlBuf: String?, @JceId(10) val msgCtrlBuf: String?,
@SerialId(11) val serverBuf: ByteArray?, @JceId(11) val serverBuf: ByteArray?,
@SerialId(12) val pingFlag: Long?, @JceId(12) val pingFlag: Long?,
@SerialId(13) val svrip: Int? @JceId(13) val svrip: Int?
) : JceStruct, Packet ) : JceStruct, Packet
@Serializable @Serializable
internal class MsgInfo( internal class MsgInfo(
@SerialId(0) val lFromUin: Long? = 0L, @JceId(0) val lFromUin: Long? = 0L,
@SerialId(1) val uMsgTime: Long? = 0L, @JceId(1) val uMsgTime: Long? = 0L,
@SerialId(2) val shMsgType: Short, @JceId(2) val shMsgType: Short,
@SerialId(3) val shMsgSeq: Short, @JceId(3) val shMsgSeq: Short,
@SerialId(4) val strMsg: String?, @JceId(4) val strMsg: String?,
@SerialId(5) val uRealMsgTime: Int?, @JceId(5) val uRealMsgTime: Int?,
@SerialId(6) val vMsg: ByteArray?, @JceId(6) val vMsg: ByteArray?,
@SerialId(7) val uAppShareID: Long?, @JceId(7) val uAppShareID: Long?,
@SerialId(8) val vMsgCookies: ByteArray? = EMPTY_BYTE_ARRAY, @JceId(8) val vMsgCookies: ByteArray? = EMPTY_BYTE_ARRAY,
@SerialId(9) val vAppShareCookie: ByteArray? = EMPTY_BYTE_ARRAY, @JceId(9) val vAppShareCookie: ByteArray? = EMPTY_BYTE_ARRAY,
@SerialId(10) val lMsgUid: Long?, @JceId(10) val lMsgUid: Long?,
@SerialId(11) val lLastChangeTime: Long?, @JceId(11) val lLastChangeTime: Long?,
@SerialId(12) val vCPicInfo: List<CPicInfo>?, @JceId(12) val vCPicInfo: List<CPicInfo>?,
@SerialId(13) val stShareData: ShareData?, @JceId(13) val stShareData: ShareData?,
@SerialId(14) val lFromInstId: Long?, @JceId(14) val lFromInstId: Long?,
@SerialId(15) val vRemarkOfSender: ByteArray?, @JceId(15) val vRemarkOfSender: ByteArray?,
@SerialId(16) val strFromMobile: String?, @JceId(16) val strFromMobile: String?,
@SerialId(17) val strFromName: String?, @JceId(17) val strFromName: String?,
@SerialId(18) val vNickName: List<String>?//, @JceId(18) val vNickName: List<String>?//,
//@SerialId(19) val stC2CTmpMsgHead: TempMsgHead? //@SerialId(19) val stC2CTmpMsgHead: TempMsgHead?
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class ShareData( internal class ShareData(
@SerialId(0) val pkgname: String = "", @JceId(0) val pkgname: String = "",
@SerialId(1) val msgtail: String = "", @JceId(1) val msgtail: String = "",
@SerialId(2) val picurl: String = "", @JceId(2) val picurl: String = "",
@SerialId(3) val url: String = "" @JceId(3) val url: String = ""
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class TempMsgHead( internal class TempMsgHead(
@SerialId(0) val c2c_type: Int? = 0, @JceId(0) val c2c_type: Int? = 0,
@SerialId(1) val serviceType: Int? = 0 @JceId(1) val serviceType: Int? = 0
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class CPicInfo( internal class CPicInfo(
@SerialId(0) val vPath: ByteArray = EMPTY_BYTE_ARRAY, @JceId(0) val vPath: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(1) val vHost: ByteArray? = EMPTY_BYTE_ARRAY @JceId(1) val vHost: ByteArray? = EMPTY_BYTE_ARRAY
) : JceStruct ) : JceStruct
\ No newline at end of file
...@@ -9,38 +9,38 @@ ...@@ -9,38 +9,38 @@
package net.mamoe.mirai.qqandroid.network.protocol.data.jce package net.mamoe.mirai.qqandroid.network.protocol.data.jce
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.mamoe.mirai.qqandroid.io.JceStruct import net.mamoe.mirai.qqandroid.io.JceStruct
import net.mamoe.mirai.qqandroid.io.serialization.jce.JceId
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY 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>()
@Serializable @Serializable
internal class RequestPacket( internal class RequestPacket(
@SerialId(1) val iVersion: Short = 3, @JceId(1) val iVersion: Short? = 3,
@SerialId(2) val cPacketType: Byte = 0, @JceId(2) val cPacketType: Byte = 0,
@SerialId(3) val iMessageType: Int = 0, @JceId(3) val iMessageType: Int = 0,
@SerialId(4) val iRequestId: Int, @JceId(4) val iRequestId: Int,
@SerialId(5) val sServantName: String = "", @JceId(5) val sServantName: String = "",
@SerialId(6) val sFuncName: String = "", @JceId(6) val sFuncName: String = "",
@SerialId(7) val sBuffer: ByteArray = EMPTY_BYTE_ARRAY, @JceId(7) val sBuffer: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(8) val iTimeout: Int? = 0, @JceId(8) val iTimeout: Int? = 0,
@SerialId(9) val context: Map<String, String>? = EMPTY_MAP, @JceId(9) val context: Map<String, String>? = EMPTY_MAP,
@SerialId(10) val status: Map<String, String>? = EMPTY_MAP @JceId(10) val status: Map<String, String>? = EMPTY_MAP
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class RequestDataVersion3( internal class RequestDataVersion3(
@SerialId(0) val map: Map<String, ByteArray> // 注意: ByteArray 不能直接放序列化的 JceStruct!! 要放类似 RequestDataStructSvcReqRegister 的 @JceId(0) val map: Map<String, ByteArray> // 注意: ByteArray 不能直接放序列化的 JceStruct!! 要放类似 RequestDataStructSvcReqRegister 的
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class RequestDataVersion2( internal class RequestDataVersion2(
@SerialId(0) val map: Map<String, Map<String, ByteArray>> @JceId(0) val map: Map<String, Map<String, ByteArray>>
) : JceStruct ) : JceStruct
@Serializable @Serializable
internal class RequestDataStructSvcReqRegister( internal class RequestDataStructSvcReqRegister(
@SerialId(0) val struct: SvcReqRegister @JceId(0) val struct: SvcReqRegister
) : JceStruct ) : JceStruct
\ No newline at end of file
...@@ -9,14 +9,15 @@ ...@@ -9,14 +9,15 @@
package net.mamoe.mirai.qqandroid.network.protocol.data.jce package net.mamoe.mirai.qqandroid.network.protocol.data.jce
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId
import net.mamoe.mirai.qqandroid.io.JceStruct import net.mamoe.mirai.qqandroid.io.JceStruct
import net.mamoe.mirai.qqandroid.io.serialization.jce.JceId
@Serializable @Serializable
internal class RequestPushForceOffline( internal class RequestPushForceOffline(
@SerialId(0) val uin: Long, @JceId(0) val uin: Long,
@SerialId(1) val title: String? = "", @JceId(1) val title: String? = "",
@SerialId(2) val tips: String? = "", @JceId(2) val tips: String? = "",
@SerialId(3) val sameDevice: Byte? = null @JceId(3) val sameDevice: Byte? = null
) : JceStruct ) : JceStruct
\ No newline at end of file
...@@ -9,47 +9,47 @@ ...@@ -9,47 +9,47 @@
package net.mamoe.mirai.qqandroid.network.protocol.data.jce package net.mamoe.mirai.qqandroid.network.protocol.data.jce
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.mamoe.mirai.qqandroid.io.JceStruct import net.mamoe.mirai.qqandroid.io.JceStruct
import net.mamoe.mirai.qqandroid.io.serialization.jce.JceId
@Serializable @Serializable
internal class SvcReqRegister( internal class SvcReqRegister(
@SerialId(0) val lUin: Long = 0L, @JceId(0) val lUin: Long = 0L,
@SerialId(1) val lBid: Long = 0L, @JceId(1) val lBid: Long = 0L,
@SerialId(2) val cConnType: Byte = 0, @JceId(2) val cConnType: Byte = 0,
@SerialId(3) val sOther: String = "", @JceId(3) val sOther: String = "",
@SerialId(4) val iStatus: Int = 11, @JceId(4) val iStatus: Int = 11,
@SerialId(5) val bOnlinePush: Byte = 0, @JceId(5) val bOnlinePush: Byte = 0,
@SerialId(6) val bIsOnline: Byte = 0, @JceId(6) val bIsOnline: Byte = 0,
@SerialId(7) val bIsShowOnline: Byte = 0, @JceId(7) val bIsShowOnline: Byte = 0,
@SerialId(8) val bKikPC: Byte = 0, @JceId(8) val bKikPC: Byte = 0,
@SerialId(9) val bKikWeak: Byte = 0, @JceId(9) val bKikWeak: Byte = 0,
@SerialId(10) val timeStamp: Long = 0L, @JceId(10) val timeStamp: Long = 0L,
@SerialId(11) val iOSVersion: Long = 0L, @JceId(11) val iOSVersion: Long = 0L,
@SerialId(12) val cNetType: Byte = 0, @JceId(12) val cNetType: Byte = 0,
@SerialId(13) val sBuildVer: String? = "", @JceId(13) val sBuildVer: String? = "",
@SerialId(14) val bRegType: Byte = 0, @JceId(14) val bRegType: Byte = 0,
@SerialId(15) val vecDevParam: ByteArray? = null, @JceId(15) val vecDevParam: ByteArray? = null,
@SerialId(16) val vecGuid: ByteArray? = null, @JceId(16) val vecGuid: ByteArray? = null,
@SerialId(17) val iLocaleID: Int = 2052, @JceId(17) val iLocaleID: Int = 2052,
@SerialId(18) val bSlientPush: Byte = 0, @JceId(18) val bSlientPush: Byte = 0,
@SerialId(19) val strDevName: String? = null, @JceId(19) val strDevName: String? = null,
@SerialId(20) val strDevType: String? = null, @JceId(20) val strDevType: String? = null,
@SerialId(21) val strOSVer: String? = null, @JceId(21) val strOSVer: String? = null,
@SerialId(22) val bOpenPush: Byte = 1, @JceId(22) val bOpenPush: Byte = 1,
@SerialId(23) val iLargeSeq: Long = 0L, @JceId(23) val iLargeSeq: Long = 0L,
@SerialId(24) val iLastWatchStartTime: Long = 0L, @JceId(24) val iLastWatchStartTime: Long = 0L,
@SerialId(26) val uOldSSOIp: Long = 0L, @JceId(26) val uOldSSOIp: Long = 0L,
@SerialId(27) val uNewSSOIp: Long = 0L, @JceId(27) val uNewSSOIp: Long = 0L,
@SerialId(28) val sChannelNo: String? = null, @JceId(28) val sChannelNo: String? = null,
@SerialId(29) val lCpId: Long = 0L, @JceId(29) val lCpId: Long = 0L,
@SerialId(30) val strVendorName: String? = null, @JceId(30) val strVendorName: String? = null,
@SerialId(31) val strVendorOSName: String? = null, @JceId(31) val strVendorOSName: String? = null,
@SerialId(32) val strIOSIdfa: String? = null, @JceId(32) val strIOSIdfa: String? = null,
@SerialId(33) val bytes_0x769_reqbody: ByteArray? = null, @JceId(33) val bytes_0x769_reqbody: ByteArray? = null,
@SerialId(34) val bIsSetStatus: Byte = 0, @JceId(34) val bIsSetStatus: Byte = 0,
@SerialId(35) val vecServerBuf: ByteArray? = null, @JceId(35) val vecServerBuf: ByteArray? = null,
@SerialId(36) val bSetMute: Byte = 0 @JceId(36) val bSetMute: Byte = 0
// @SerialId(25) var vecBindUin: ArrayList<*>? = null // ?? 未知泛型 // @SerialId(25) var vecBindUin: ArrayList<*>? = null // ?? 未知泛型
) : JceStruct ) : JceStruct
\ No newline at end of file
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
package net.mamoe.mirai.qqandroid.network.protocol.data.proto package net.mamoe.mirai.qqandroid.network.protocol.data.proto
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId
import kotlinx.serialization.protobuf.ProtoNumberType import kotlinx.serialization.protobuf.ProtoNumberType
import kotlinx.serialization.protobuf.ProtoType import kotlinx.serialization.protobuf.ProtoType
import net.mamoe.mirai.qqandroid.io.ProtoBuf import net.mamoe.mirai.qqandroid.io.ProtoBuf
...@@ -22,74 +22,74 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY ...@@ -22,74 +22,74 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
class Oidb0x858 : ProtoBuf { class Oidb0x858 : ProtoBuf {
@Serializable @Serializable
class GoldMsgTipsElem( class GoldMsgTipsElem(
@SerialId(1) val type: Int = 0, @ProtoId(1) val type: Int = 0,
@SerialId(2) val billno: String = "", @ProtoId(2) val billno: String = "",
@SerialId(3) val result: Int = 0, @ProtoId(3) val result: Int = 0,
@SerialId(4) val amount: Int = 0, @ProtoId(4) val amount: Int = 0,
@SerialId(5) val total: Int = 0, @ProtoId(5) val total: Int = 0,
@SerialId(6) val interval: Int = 0, @ProtoId(6) val interval: Int = 0,
@SerialId(7) val finish: Int = 0, @ProtoId(7) val finish: Int = 0,
@SerialId(8) val uin: List<Long>? = null, @ProtoId(8) val uin: List<Long>? = null,
@SerialId(9) val action: Int = 0 @ProtoId(9) val action: Int = 0
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class MessageRecallReminder( class MessageRecallReminder(
@SerialId(1) val uin: Long = 0L, @ProtoId(1) val uin: Long = 0L,
@SerialId(2) val nickname: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(2) val nickname: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(3) val recalledMsgList: List<MessageMeta> = listOf(), @ProtoId(3) val recalledMsgList: List<MessageMeta> = listOf(),
@SerialId(4) val reminderContent: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(4) val reminderContent: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(5) val userdef: ByteArray = EMPTY_BYTE_ARRAY @ProtoId(5) val userdef: ByteArray = EMPTY_BYTE_ARRAY
) : ProtoBuf { ) : ProtoBuf {
@Serializable @Serializable
class MessageMeta( class MessageMeta(
@SerialId(1) val seq: Int = 0, @ProtoId(1) val seq: Int = 0,
@SerialId(2) val time: Int = 0, @ProtoId(2) val time: Int = 0,
@SerialId(3) val msgRandom: Int = 0 @ProtoId(3) val msgRandom: Int = 0
) : ProtoBuf ) : ProtoBuf
} }
@Serializable @Serializable
class NotifyMsgBody( class NotifyMsgBody(
@SerialId(1) val optEnumType: Int /* enum */ = 5, @ProtoId(1) val optEnumType: Int /* enum */ = 5,
@SerialId(2) val optUint64MsgTime: Long = 0L, @ProtoId(2) val optUint64MsgTime: Long = 0L,
@SerialId(3) val optUint64MsgExpires: Long = 0L, @ProtoId(3) val optUint64MsgExpires: Long = 0L,
@SerialId(4) val optUint64ConfUin: Long = 0L, @ProtoId(4) val optUint64ConfUin: Long = 0L,
@SerialId(5) val optMsgRedtips: RedGrayTipsInfo? = null, @ProtoId(5) val optMsgRedtips: RedGrayTipsInfo? = null,
@SerialId(6) val optMsgRecallReminder: MessageRecallReminder? = null, @ProtoId(6) val optMsgRecallReminder: MessageRecallReminder? = null,
@SerialId(7) val optMsgObjUpdate: NotifyObjmsgUpdate? = null, @ProtoId(7) val optMsgObjUpdate: NotifyObjmsgUpdate? = null,
// @SerialId(8) val optStcmGameState: ApolloGameStatus.STCMGameMessage? = null, // @SerialId(8) val optStcmGameState: ApolloGameStatus.STCMGameMessage? = null,
// @SerialId(9) val aplloMsgPush: ApolloPushMsgInfo.STPushMsgElem? = null, // @SerialId(9) val aplloMsgPush: ApolloPushMsgInfo.STPushMsgElem? = null,
@SerialId(10) val optMsgGoldtips: GoldMsgTipsElem? = null @ProtoId(10) val optMsgGoldtips: GoldMsgTipsElem? = null
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class NotifyObjmsgUpdate( class NotifyObjmsgUpdate(
@SerialId(1) val objmsgId: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(1) val objmsgId: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(2) val updateType: Int = 0, @ProtoId(2) val updateType: Int = 0,
@SerialId(3) val extMsg: ByteArray = EMPTY_BYTE_ARRAY @ProtoId(3) val extMsg: ByteArray = EMPTY_BYTE_ARRAY
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class RedGrayTipsInfo( class RedGrayTipsInfo(
@SerialId(1) val optUint32ShowLastest: Int = 0, @ProtoId(1) val optUint32ShowLastest: Int = 0,
@SerialId(2) val senderUin: Long = 0L, @ProtoId(2) val senderUin: Long = 0L,
@SerialId(3) val receiverUin: Long = 0L, @ProtoId(3) val receiverUin: Long = 0L,
@SerialId(4) val senderRichContent: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(4) val senderRichContent: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(5) val receiverRichContent: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(5) val receiverRichContent: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(6) val authkey: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(6) val authkey: ByteArray = EMPTY_BYTE_ARRAY,
@ProtoType(ProtoNumberType.SIGNED) @SerialId(7) val sint32Msgtype: Int = 0, @ProtoType(ProtoNumberType.SIGNED) @ProtoId(7) val sint32Msgtype: Int = 0,
@SerialId(8) val luckyFlag: Int = 0, @ProtoId(8) val luckyFlag: Int = 0,
@SerialId(9) val hideFlag: Int = 0, @ProtoId(9) val hideFlag: Int = 0,
@SerialId(10) val pcBody: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(10) val pcBody: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(11) val icon: Int = 0, @ProtoId(11) val icon: Int = 0,
@SerialId(12) val luckyUin: Long = 0L, @ProtoId(12) val luckyUin: Long = 0L,
@SerialId(13) val time: Int = 0, @ProtoId(13) val time: Int = 0,
@SerialId(14) val random: Int = 0, @ProtoId(14) val random: Int = 0,
@SerialId(15) val broadcastRichContent: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(15) val broadcastRichContent: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(16) val idiom: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(16) val idiom: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(17) val idiomSeq: Int = 0, @ProtoId(17) val idiomSeq: Int = 0,
@SerialId(18) val idiomAlpha: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(18) val idiomAlpha: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(19) val jumpurl: ByteArray = EMPTY_BYTE_ARRAY @ProtoId(19) val jumpurl: ByteArray = EMPTY_BYTE_ARRAY
) : ProtoBuf ) : ProtoBuf
} }
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
package net.mamoe.mirai.qqandroid.network.protocol.data.proto package net.mamoe.mirai.qqandroid.network.protocol.data.proto
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId
import net.mamoe.mirai.qqandroid.io.ProtoBuf import net.mamoe.mirai.qqandroid.io.ProtoBuf
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
...@@ -18,40 +18,40 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY ...@@ -18,40 +18,40 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
internal class Vec0xd50 : ProtoBuf { internal class Vec0xd50 : ProtoBuf {
@Serializable @Serializable
internal class ExtSnsFrdData( internal class ExtSnsFrdData(
@SerialId(1) val frdUin: Long = 0L, @ProtoId(1) val frdUin: Long = 0L,
@SerialId(91001) val musicSwitch: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(91001) val musicSwitch: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(101001) val mutualmarkAlienation: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(101001) val mutualmarkAlienation: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(141001) val mutualmarkScore: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(141001) val mutualmarkScore: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(151001) val ksingSwitch: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(151001) val ksingSwitch: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(181001) val lbsShare: ByteArray = EMPTY_BYTE_ARRAY @ProtoId(181001) val lbsShare: ByteArray = EMPTY_BYTE_ARRAY
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
internal class RspBody( internal class RspBody(
@SerialId(1) val msgUpdateData: List<Vec0xd50.ExtSnsFrdData>? = null, @ProtoId(1) val msgUpdateData: List<Vec0xd50.ExtSnsFrdData>? = null,
@SerialId(11) val over: Int = 0, @ProtoId(11) val over: Int = 0,
@SerialId(12) val nextStart: Int = 0, @ProtoId(12) val nextStart: Int = 0,
@SerialId(13) val uint64UnfinishedUins: List<Long>? = null @ProtoId(13) val uint64UnfinishedUins: List<Long>? = null
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
internal class ReqBody( internal class ReqBody(
@SerialId(1) val appid: Long = 0L, @ProtoId(1) val appid: Long = 0L,
@SerialId(2) val maxPkgSize: Int = 0, @ProtoId(2) val maxPkgSize: Int = 0,
@SerialId(3) val startTime: Int = 0, @ProtoId(3) val startTime: Int = 0,
@SerialId(4) val startIndex: Int = 0, @ProtoId(4) val startIndex: Int = 0,
@SerialId(5) val reqNum: Int = 0, @ProtoId(5) val reqNum: Int = 0,
@SerialId(6) val uinList: List<Long>? = null, @ProtoId(6) val uinList: List<Long>? = null,
@SerialId(91001) val reqMusicSwitch: Int = 0, @ProtoId(91001) val reqMusicSwitch: Int = 0,
@SerialId(101001) val reqMutualmarkAlienation: Int = 0, @ProtoId(101001) val reqMutualmarkAlienation: Int = 0,
@SerialId(141001) val reqMutualmarkScore: Int = 0, @ProtoId(141001) val reqMutualmarkScore: Int = 0,
@SerialId(151001) val reqKsingSwitch: Int = 0, @ProtoId(151001) val reqKsingSwitch: Int = 0,
@SerialId(181001) val reqMutualmarkLbsshare: Int = 0 @ProtoId(181001) val reqMutualmarkLbsshare: Int = 0
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
internal class KSingRelationInfo( internal class KSingRelationInfo(
@SerialId(1) val flag: Int = 0 @ProtoId(1) val flag: Int = 0
) : ProtoBuf ) : ProtoBuf
} }
...@@ -59,21 +59,21 @@ internal class Vec0xd50 : ProtoBuf { ...@@ -59,21 +59,21 @@ internal class Vec0xd50 : ProtoBuf {
internal class Vec0xd6b : ProtoBuf { internal class Vec0xd6b : ProtoBuf {
@Serializable @Serializable
internal class ReqBody( internal class ReqBody(
@SerialId(1) val maxPkgSize: Int = 0, @ProtoId(1) val maxPkgSize: Int = 0,
@SerialId(2) val startTime: Int = 0, @ProtoId(2) val startTime: Int = 0,
@SerialId(11) val uinList: List<Long>? = null @ProtoId(11) val uinList: List<Long>? = null
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
internal class RspBody( internal class RspBody(
@SerialId(11) val msgMutualmarkData: List<Vec0xd6b.MutualMarkData>? = null, @ProtoId(11) val msgMutualmarkData: List<Vec0xd6b.MutualMarkData>? = null,
@SerialId(12) val uint64UnfinishedUins: List<Long>? = null @ProtoId(12) val uint64UnfinishedUins: List<Long>? = null
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
internal class MutualMarkData( internal class MutualMarkData(
@SerialId(1) val frdUin: Long = 0L, @ProtoId(1) val frdUin: Long = 0L,
@SerialId(2) val result: Int = 0 @ProtoId(2) val result: Int = 0
// @SerialId(11) val mutualmarkInfo: List<Mutualmark.MutualMark>? = null // @SerialId(11) val mutualmarkInfo: List<Mutualmark.MutualMark>? = null
) : ProtoBuf ) : ProtoBuf
} }
...@@ -82,26 +82,26 @@ internal class Vec0xd6b : ProtoBuf { ...@@ -82,26 +82,26 @@ internal class Vec0xd6b : ProtoBuf {
internal class Mutualmark : ProtoBuf { internal class Mutualmark : ProtoBuf {
@Serializable @Serializable
internal class MutualmarkInfo( internal class MutualmarkInfo(
@SerialId(1) val lastActionTime: Long = 0L, @ProtoId(1) val lastActionTime: Long = 0L,
@SerialId(2) val level: Int = 0, @ProtoId(2) val level: Int = 0,
@SerialId(3) val lastChangeTime: Long = 0L, @ProtoId(3) val lastChangeTime: Long = 0L,
@SerialId(4) val continueDays: Int = 0, @ProtoId(4) val continueDays: Int = 0,
@SerialId(5) val wildcardWording: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(5) val wildcardWording: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(6) val notifyTime: Long = 0L, @ProtoId(6) val notifyTime: Long = 0L,
@SerialId(7) val iconStatus: Long = 0L, @ProtoId(7) val iconStatus: Long = 0L,
@SerialId(8) val iconStatusEndTime: Long = 0L, @ProtoId(8) val iconStatusEndTime: Long = 0L,
@SerialId(9) val closeFlag: Int = 0, @ProtoId(9) val closeFlag: Int = 0,
@SerialId(10) val resourceInfo: ByteArray = EMPTY_BYTE_ARRAY @ProtoId(10) val resourceInfo: ByteArray = EMPTY_BYTE_ARRAY
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
internal class ResourceInfo17( internal class ResourceInfo17(
@SerialId(1) val dynamicUrl: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(1) val dynamicUrl: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(2) val staticUrl: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(2) val staticUrl: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(3) val cartoonUrl: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(3) val cartoonUrl: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(4) val cartoonMd5: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(4) val cartoonMd5: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(5) val playCartoon: Int = 0, @ProtoId(5) val playCartoon: Int = 0,
@SerialId(6) val word: ByteArray = EMPTY_BYTE_ARRAY @ProtoId(6) val word: ByteArray = EMPTY_BYTE_ARRAY
) : ProtoBuf ) : ProtoBuf
} }
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
package net.mamoe.mirai.qqandroid.network.protocol.data.proto package net.mamoe.mirai.qqandroid.network.protocol.data.proto
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId
import net.mamoe.mirai.qqandroid.io.ProtoBuf import net.mamoe.mirai.qqandroid.io.ProtoBuf
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
...@@ -18,51 +18,51 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY ...@@ -18,51 +18,51 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
class GroupLabel : ProtoBuf { class GroupLabel : ProtoBuf {
@Serializable @Serializable
class Label( class Label(
@SerialId(1) val name: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(1) val name: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(2) val enumType: Int /* enum */ = 1, @ProtoId(2) val enumType: Int /* enum */ = 1,
@SerialId(3) val textColor: GroupLabel.Color? = null, @ProtoId(3) val textColor: GroupLabel.Color? = null,
@SerialId(4) val edgingColor: GroupLabel.Color? = null, @ProtoId(4) val edgingColor: GroupLabel.Color? = null,
@SerialId(5) val labelAttr: Int = 0, @ProtoId(5) val labelAttr: Int = 0,
@SerialId(6) val labelType: Int = 0 @ProtoId(6) val labelType: Int = 0
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class RspBody( class RspBody(
@SerialId(1) val error: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(1) val error: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(2) val groupInfo: List<GroupLabel.GroupInfo>? = null @ProtoId(2) val groupInfo: List<GroupLabel.GroupInfo>? = null
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class SourceId( class SourceId(
@SerialId(1) val sourceId: Int = 0 @ProtoId(1) val sourceId: Int = 0
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class GroupInfo( class GroupInfo(
@SerialId(1) val int32Result: Int = 0, @ProtoId(1) val int32Result: Int = 0,
@SerialId(2) val groupCode: Long = 0L, @ProtoId(2) val groupCode: Long = 0L,
@SerialId(3) val groupLabel: List<GroupLabel.Label>? = null @ProtoId(3) val groupLabel: List<GroupLabel.Label>? = null
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class Color( class Color(
@SerialId(1) val r: Int = 0, @ProtoId(1) val r: Int = 0,
@SerialId(2) val g: Int = 0, @ProtoId(2) val g: Int = 0,
@SerialId(3) val b: Int = 0 @ProtoId(3) val b: Int = 0
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class ReqBody( class ReqBody(
@SerialId(1) val sourceId: GroupLabel.SourceId? = null, @ProtoId(1) val sourceId: GroupLabel.SourceId? = null,
@SerialId(2) val uinInfo: GroupLabel.UinInfo? = null, @ProtoId(2) val uinInfo: GroupLabel.UinInfo? = null,
@SerialId(3) val numberLabel: Int = 5, @ProtoId(3) val numberLabel: Int = 5,
@SerialId(4) val groupCode: List<Long>? = null, @ProtoId(4) val groupCode: List<Long>? = null,
@SerialId(5) val labelStyle: Int = 0 @ProtoId(5) val labelStyle: Int = 0
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class UinInfo( class UinInfo(
@SerialId(1) val int64Longitude: Long = 0L, @ProtoId(1) val int64Longitude: Long = 0L,
@SerialId(2) val int64Latitude: Long = 0L @ProtoId(2) val int64Latitude: Long = 0L
) : ProtoBuf ) : ProtoBuf
} }
\ No newline at end of file
...@@ -19,7 +19,7 @@ import net.mamoe.mirai.utils.cryptor.ECDHKeyPair ...@@ -19,7 +19,7 @@ import net.mamoe.mirai.utils.cryptor.ECDHKeyPair
import net.mamoe.mirai.utils.io.encryptAndWrite import net.mamoe.mirai.utils.io.encryptAndWrite
import net.mamoe.mirai.utils.io.writeShortLVByteArray import net.mamoe.mirai.utils.io.writeShortLVByteArray
@UseExperimental(ExperimentalUnsignedTypes::class) @OptIn(ExperimentalUnsignedTypes::class)
internal interface EncryptMethod { internal interface EncryptMethod {
val id: Int val id: Int
......
...@@ -123,7 +123,8 @@ internal class FriendList { ...@@ -123,7 +123,8 @@ internal class FriendList {
} }
} }
internal object GetFriendGroupList : OutgoingPacketFactory<GetFriendGroupList.Response>("friendlist.getFriendGroupList") { internal object GetFriendGroupList :
OutgoingPacketFactory<GetFriendGroupList.Response>("friendlist.getFriendGroupList") {
class Response( class Response(
val totalFriendCount: Short, val totalFriendCount: Short,
......
...@@ -21,7 +21,7 @@ import kotlin.jvm.JvmName ...@@ -21,7 +21,7 @@ import kotlin.jvm.JvmName
/** /**
* Inline the block * Inline the block
*/ */
@UseExperimental(ExperimentalContracts::class) @OptIn(ExperimentalContracts::class)
@PublishedApi @PublishedApi
internal inline fun <R> inline(block: () -> R): R { internal inline fun <R> inline(block: () -> R): R {
contract { contract {
......
This diff is collapsed.
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