Commit 3ae1832a authored by jiahua.liu's avatar jiahua.liu

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt
parents 92b7b10f 18f860b9
...@@ -39,8 +39,7 @@ QQ for Android (8.2.0 版本,2019 年 12 月)协议的实现,目前还 ...@@ -39,8 +39,7 @@ QQ for Android (8.2.0 版本,2019 年 12 月)协议的实现,目前还
- 完成 密码登录 (2020/1/23) - 完成 密码登录 (2020/1/23)
- 完成 群消息解析 (2020/1/25) - 完成 群消息解析 (2020/1/25)
- 完成 图片验证码登录 (2020/1/26) - 完成 图片验证码登录 (2020/1/26)
- 进行中 免密登录 - 完成 设备锁登录 (2020/1/29)
- 进行中 SMS 登录
- 进行中 消息解析和发送 - 进行中 消息解析和发送
- 进行中 图片上传和下载 - 进行中 图片上传和下载
......
package net.mamoe.mirai.qqandroid package net.mamoe.mirai.qqandroid
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.FriendNameRemark import net.mamoe.mirai.data.FriendNameRemark
import net.mamoe.mirai.data.GroupInfo import net.mamoe.mirai.data.GroupInfo
...@@ -8,16 +7,19 @@ import net.mamoe.mirai.data.PreviousNameList ...@@ -8,16 +7,19 @@ import net.mamoe.mirai.data.PreviousNameList
import net.mamoe.mirai.data.Profile import net.mamoe.mirai.data.Profile
import net.mamoe.mirai.message.data.ImageId import net.mamoe.mirai.message.data.ImageId
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
internal abstract class ContactImpl : Contact internal abstract class ContactImpl : Contact
internal class QQImpl(bot: Bot, override val coroutineContext: CoroutineContext, override val id: Long) : ContactImpl(), QQ { internal class QQImpl(bot: QQAndroidBot, override val coroutineContext: CoroutineContext, override val id: Long) : ContactImpl(), QQ {
override val bot: Bot by bot.unsafeWeakRef() override val bot: QQAndroidBot by bot.unsafeWeakRef()
override suspend fun sendMessage(message: MessageChain) { override suspend fun sendMessage(message: MessageChain) {
TODO("not implemented") bot.network.run {
MessageSvc.PbSendMsg.ToFriend(bot.client, id, message).sendAndExpect<MessageSvc.PbSendMsg.Response>()
}
} }
override suspend fun uploadImage(image: ExternalImage): ImageId { override suspend fun uploadImage(image: ExternalImage): ImageId {
...@@ -38,11 +40,11 @@ internal class QQImpl(bot: Bot, override val coroutineContext: CoroutineContext, ...@@ -38,11 +40,11 @@ internal class QQImpl(bot: Bot, override val coroutineContext: CoroutineContext,
} }
internal class MemberImpl(bot: Bot, group: Group, override val coroutineContext: CoroutineContext, override val id: Long) : ContactImpl(), Member { internal class MemberImpl(bot: QQAndroidBot, group: Group, override val coroutineContext: CoroutineContext, override val id: Long) : ContactImpl(), Member {
override val group: Group by group.unsafeWeakRef() override val group: Group by group.unsafeWeakRef()
override val permission: MemberPermission override val permission: MemberPermission
get() = TODO("not implemented") get() = TODO("not implemented")
override val bot: Bot by bot.unsafeWeakRef() override val bot: QQAndroidBot by bot.unsafeWeakRef()
override suspend fun mute(durationSeconds: Int): Boolean { override suspend fun mute(durationSeconds: Int): Boolean {
TODO("not implemented") TODO("not implemented")
...@@ -76,7 +78,7 @@ internal class MemberImpl(bot: Bot, group: Group, override val coroutineContext: ...@@ -76,7 +78,7 @@ internal class MemberImpl(bot: Bot, group: Group, override val coroutineContext:
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
internal class GroupImpl(bot: Bot, override val coroutineContext: CoroutineContext, override val id: Long) : ContactImpl(), Group { internal class GroupImpl(bot: QQAndroidBot, override val coroutineContext: CoroutineContext, override val id: Long) : ContactImpl(), Group {
override val internalId: GroupInternalId = GroupId(id).toInternalId() override val internalId: GroupInternalId = GroupId(id).toInternalId()
override val owner: Member override val owner: Member
get() = TODO("not implemented") get() = TODO("not implemented")
...@@ -86,7 +88,8 @@ internal class GroupImpl(bot: Bot, override val coroutineContext: CoroutineConte ...@@ -86,7 +88,8 @@ internal class GroupImpl(bot: Bot, override val coroutineContext: CoroutineConte
get() = TODO("not implemented") get() = TODO("not implemented")
override val members: ContactList<Member> = ContactList(LockFreeLinkedList()) override val members: ContactList<Member> = ContactList(LockFreeLinkedList())
override fun getMember(id: Long): Member = members.delegate.filteringGetOrAdd({ it.id == id }, { MemberImpl(bot, this, coroutineContext, id) }) override fun getMember(id: Long): Member =
members.delegate.filteringGetOrAdd({ it.id == id }, { MemberImpl(bot as QQAndroidBot, this, coroutineContext, id) })
override suspend fun updateGroupInfo(): GroupInfo { override suspend fun updateGroupInfo(): GroupInfo {
TODO("not implemented") TODO("not implemented")
...@@ -96,7 +99,7 @@ internal class GroupImpl(bot: Bot, override val coroutineContext: CoroutineConte ...@@ -96,7 +99,7 @@ internal class GroupImpl(bot: Bot, override val coroutineContext: CoroutineConte
TODO("not implemented") TODO("not implemented")
} }
override val bot: Bot by bot.unsafeWeakRef() override val bot: QQAndroidBot by bot.unsafeWeakRef()
override suspend fun sendMessage(message: MessageChain) { override suspend fun sendMessage(message: MessageChain) {
TODO("not implemented") TODO("not implemented")
......
...@@ -33,7 +33,7 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -33,7 +33,7 @@ internal abstract class QQAndroidBotBase constructor(
override val qqs: ContactList<QQ> = ContactList(LockFreeLinkedList()) override val qqs: ContactList<QQ> = ContactList(LockFreeLinkedList())
override fun getQQ(id: Long): QQ { override fun getQQ(id: Long): QQ {
return qqs.delegate.filteringGetOrAdd({ it.id == id }, { QQImpl(this, coroutineContext, id) }) return qqs.delegate.filteringGetOrAdd({ it.id == id }, { QQImpl(this as QQAndroidBot, coroutineContext, id) })
} }
override fun createNetworkHandler(coroutineContext: CoroutineContext): QQAndroidBotNetworkHandler { override fun createNetworkHandler(coroutineContext: CoroutineContext): QQAndroidBotNetworkHandler {
...@@ -43,17 +43,17 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -43,17 +43,17 @@ internal abstract class QQAndroidBotBase constructor(
override val groups: ContactList<Group> = ContactList(LockFreeLinkedList()) override val groups: ContactList<Group> = ContactList(LockFreeLinkedList())
override suspend fun getGroup(id: GroupId): Group { override suspend fun getGroup(id: GroupId): Group {
return groups.delegate.filteringGetOrAdd({ it.id == id.value }, { GroupImpl(this, coroutineContext, id.value) }) return groups.delegate.filteringGetOrAdd({ it.id == id.value }, { GroupImpl(this as QQAndroidBot, coroutineContext, id.value) })
} }
override suspend fun getGroup(internalId: GroupInternalId): Group { override suspend fun getGroup(internalId: GroupInternalId): Group {
internalId.toId().value.let { id -> internalId.toId().value.let { id ->
return groups.delegate.filteringGetOrAdd({ it.id == id }, { GroupImpl(this, coroutineContext, id) }) return groups.delegate.filteringGetOrAdd({ it.id == id }, { GroupImpl(this as QQAndroidBot, coroutineContext, id) })
} }
} }
override suspend fun getGroup(id: Long): Group { override suspend fun getGroup(id: Long): Group {
return groups.delegate.filteringGetOrAdd({ it.id == id }, { GroupImpl(this, coroutineContext, id) }) return groups.delegate.filteringGetOrAdd({ it.id == id }, { GroupImpl(this as QQAndroidBot, coroutineContext, id) })
} }
override suspend fun Image.getLink(): ImageLink { override suspend fun Image.getLink(): ImageLink {
......
...@@ -7,7 +7,7 @@ import net.mamoe.mirai.event.events.BotEvent ...@@ -7,7 +7,7 @@ import net.mamoe.mirai.event.events.BotEvent
/** /**
* 被挤下线 * 被挤下线
*/ */
class ForceOfflineEvent( data class ForceOfflineEvent(
override val bot: Bot, override val bot: Bot,
val title: String, val title: String,
val tips: String val tips: String
......
...@@ -6,6 +6,8 @@ import kotlinx.io.core.readBytes ...@@ -6,6 +6,8 @@ import kotlinx.io.core.readBytes
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.SerializationStrategy
import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import net.mamoe.mirai.utils.io.toUHexString
/** /**
* 仅有标示作用 * 仅有标示作用
...@@ -13,26 +15,29 @@ import kotlinx.serialization.SerializationStrategy ...@@ -13,26 +15,29 @@ import kotlinx.serialization.SerializationStrategy
interface ProtoBuf interface ProtoBuf
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).also {
println("发送 protobuf: ${it.toUHexString()}")
})
} }
/** /**
* dump * dump
*/ */
fun <T : ProtoBuf> T.toByteArray(serializer: SerializationStrategy<T>): ByteArray { fun <T : ProtoBuf> T.toByteArray(serializer: SerializationStrategy<T>): ByteArray {
return kotlinx.serialization.protobuf.ProtoBuf.dump(serializer, this) return ProtoBufWithNullableSupport.dump(serializer, this)
} }
/** /**
* load * load
*/ */
fun <T : ProtoBuf> ByteArray.loadAs(deserializer: DeserializationStrategy<T>): T { fun <T : ProtoBuf> ByteArray.loadAs(deserializer: DeserializationStrategy<T>): T {
return kotlinx.serialization.protobuf.ProtoBuf.load(deserializer, this) return ProtoBufWithNullableSupport.load(deserializer, this)
} }
/** /**
* load * load
*/ */
fun <T : ProtoBuf> Input.readRemainingAsProtoBuf(serializer: DeserializationStrategy<T>): T { fun <T : ProtoBuf> Input.readRemainingAsProtoBuf(serializer: DeserializationStrategy<T>): T {
return kotlinx.serialization.protobuf.ProtoBuf.load(serializer, this.readBytes()) return ProtoBufWithNullableSupport.load(serializer, this.readBytes())
} }
\ No newline at end of file
...@@ -191,7 +191,7 @@ class Jce private constructor(private val charset: JceCharset, context: SerialMo ...@@ -191,7 +191,7 @@ class Jce private constructor(private val charset: JceCharset, context: SerialMo
this.writeHead(STRUCT_END, 0) this.writeHead(STRUCT_END, 0)
} }
} else if (value is ProtoBuf) { } else if (value is ProtoBuf) {
this.encodeTaggedByteArray(popTag(), kotlinx.serialization.protobuf.ProtoBuf.dump(value)) this.encodeTaggedByteArray(popTag(), net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport.dump(value))
} else { } else {
serializer.serialize(this, value) serializer.serialize(this, value)
} }
......
...@@ -314,10 +314,14 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler ...@@ -314,10 +314,14 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
suspend fun <E : Packet> OutgoingPacket.sendAndExpect(): E { suspend fun <E : Packet> OutgoingPacket.sendAndExpect(): E {
val handler = PacketListener(commandName = commandName, sequenceId = sequenceId) val handler = PacketListener(commandName = commandName, sequenceId = sequenceId)
packetListeners.addLast(handler) packetListeners.addLast(handler)
bot.logger.info("Send: ${this.commandName}")
channel.send(delegate) channel.send(delegate)
return withTimeout(3000) { return withTimeoutOrNull(3000) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
handler.await() as E handler.await() as E
} ?: net.mamoe.mirai.qqandroid.utils.inline {
packetListeners.remove(handler)
error("timeout when sending ${this.commandName}")
} }
} }
......
...@@ -469,7 +469,7 @@ class ImMsgBody : ProtoBuf { ...@@ -469,7 +469,7 @@ class ImMsgBody : ProtoBuf {
@SerialId(16) val bubbleSubId: Int = 0, @SerialId(16) val bubbleSubId: Int = 0,
@SerialId(17) val pendantId: Long = 0L, @SerialId(17) val pendantId: Long = 0L,
@SerialId(18) val rpIndex: ByteArray = EMPTY_BYTE_ARRAY, @SerialId(18) val rpIndex: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(19) val pbReserve: ByteArray = EMPTY_BYTE_ARRAY @SerialId(19) val pbReserve: ByteArray = EMPTY_BYTE_ARRAY // 78 00 F8 01 00 C8 02 00
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
...@@ -609,7 +609,7 @@ class ImMsgBody : ProtoBuf { ...@@ -609,7 +609,7 @@ class ImMsgBody : ProtoBuf {
@SerialId(8) val reserved: Int = 0, @SerialId(8) val reserved: Int = 0,
@SerialId(9) val subcmd: Int = 0, @SerialId(9) val subcmd: Int = 0,
@SerialId(10) val microCloud: Int = 0, @SerialId(10) val microCloud: Int = 0,
@SerialId(11) val bytesFileUrls: List<ByteArray>? = null, @SerialId(11) val bytesFileUrls: List<ByteArray>? = listOf(),
@SerialId(12) val downloadFlag: Int = 0, @SerialId(12) val downloadFlag: Int = 0,
@SerialId(50) val dangerEvel: Int = 0, @SerialId(50) val dangerEvel: Int = 0,
@SerialId(51) val lifeTime: Int = 0, @SerialId(51) val lifeTime: Int = 0,
...@@ -705,7 +705,7 @@ class ImMsgBody : ProtoBuf { ...@@ -705,7 +705,7 @@ class ImMsgBody : ProtoBuf {
@SerialId(20) val downPara: ByteArray = EMPTY_BYTE_ARRAY, @SerialId(20) val downPara: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(29) val format: Int = 0, @SerialId(29) val format: Int = 0,
@SerialId(30) val pbReserve: ByteArray = EMPTY_BYTE_ARRAY, @SerialId(30) val pbReserve: ByteArray = EMPTY_BYTE_ARRAY,
@SerialId(31) val bytesPttUrls: List<ByteArray>? = null, @SerialId(31) val bytesPttUrls: List<ByteArray>? = listOf(),
@SerialId(32) val downloadFlag: Int = 0 @SerialId(32) val downloadFlag: Int = 0
) : ProtoBuf ) : ProtoBuf
...@@ -813,8 +813,8 @@ class ImMsgBody : ProtoBuf { ...@@ -813,8 +813,8 @@ class ImMsgBody : ProtoBuf {
class RichText( class RichText(
@SerialId(1) val attr: Attr? = null, @SerialId(1) val attr: Attr? = null,
@SerialId(2) val elems: MutableList<Elem> = mutableListOf(), @SerialId(2) val elems: MutableList<Elem> = mutableListOf(),
@SerialId(3) val notOnlineFile: NotOnlineFile? = null, @SerialId(3) val notOnlineFile: NotOnlineFile? =null,
@SerialId(4) val ptt: Ptt? = null, @SerialId(4) val ptt: Ptt? =null,
@SerialId(5) val tmpPtt: TmpPtt? = null, @SerialId(5) val tmpPtt: TmpPtt? = null,
@SerialId(6) val trans211TmpMsg: Trans211TmpMsg? = null @SerialId(6) val trans211TmpMsg: Trans211TmpMsg? = null
) : ProtoBuf ) : ProtoBuf
...@@ -1045,9 +1045,9 @@ class ImMsgHead : ProtoBuf { ...@@ -1045,9 +1045,9 @@ class ImMsgHead : ProtoBuf {
@Serializable @Serializable
class InstCtrl( class InstCtrl(
@SerialId(1) val msgSendToInst: List<InstInfo>? = null, @SerialId(1) val msgSendToInst: List<InstInfo>? = listOf(),
@SerialId(2) val msgExcludeInst: List<InstInfo>? = null, @SerialId(2) val msgExcludeInst: List<InstInfo>? = listOf(),
@SerialId(3) val msgFromInst: InstInfo? = null @SerialId(3) val msgFromInst: InstInfo? = InstInfo()
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
...@@ -1107,7 +1107,7 @@ class ImReceipt : ProtoBuf { ...@@ -1107,7 +1107,7 @@ class ImReceipt : ProtoBuf {
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class ReceiptInfo( data class ReceiptInfo(
@SerialId(1) val readTime: Long = 0L @SerialId(1) val readTime: Long = 0L
) : ProtoBuf ) : ProtoBuf
...@@ -1118,7 +1118,7 @@ class ImReceipt : ProtoBuf { ...@@ -1118,7 +1118,7 @@ class ImReceipt : ProtoBuf {
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class ReceiptResp( data class ReceiptResp(
@SerialId(1) val command: Int /* enum */ = 1, @SerialId(1) val command: Int /* enum */ = 1,
@SerialId(2) val receiptInfo: ReceiptInfo? = null @SerialId(2) val receiptInfo: ReceiptInfo? = null
) : ProtoBuf ) : ProtoBuf
......
...@@ -2,6 +2,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.data.proto ...@@ -2,6 +2,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.data.proto
import kotlinx.serialization.SerialId import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.mamoe.mirai.data.Packet
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
...@@ -102,7 +103,7 @@ class MsgSvc : ProtoBuf { ...@@ -102,7 +103,7 @@ class MsgSvc : ProtoBuf {
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class MsgSendInfo( data class MsgSendInfo(
@SerialId(1) val receiver: Int = 0 @SerialId(1) val receiver: Int = 0
) : ProtoBuf ) : ProtoBuf
...@@ -440,7 +441,7 @@ class MsgSvc : ProtoBuf { ...@@ -440,7 +441,7 @@ class MsgSvc : ProtoBuf {
) : ProtoBuf ) : ProtoBuf
@Serializable @Serializable
class PbSendMsgResp( data class PbSendMsgResp(
@SerialId(1) val result: Int = 0, @SerialId(1) val result: Int = 0,
@SerialId(2) val errmsg: String = "", @SerialId(2) val errmsg: String = "",
@SerialId(3) val sendTime: Int = 0, @SerialId(3) val sendTime: Int = 0,
...@@ -450,7 +451,7 @@ class MsgSvc : ProtoBuf { ...@@ -450,7 +451,7 @@ class MsgSvc : ProtoBuf {
@SerialId(7) val transSvrInfo: TransSvrInfo? = null, @SerialId(7) val transSvrInfo: TransSvrInfo? = null,
@SerialId(8) val receiptResp: ImReceipt.ReceiptResp? = null, @SerialId(8) val receiptResp: ImReceipt.ReceiptResp? = null,
@SerialId(9) val textAnalysisResult: Int = 0 @SerialId(9) val textAnalysisResult: Int = 0
) : ProtoBuf ) : ProtoBuf, Packet
@Serializable @Serializable
class PbBindUinUnReadMsgNumResp( class PbBindUinUnReadMsgNumResp(
......
package net.mamoe.mirai.qqandroid.network.protocol.packet package net.mamoe.mirai.qqandroid.network.protocol.packet
import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
interface MessageMicro interface MessageMicro
fun <T : MessageMicro> T.toByteArray(serializer: SerializationStrategy<T>): ByteArray = ProtoBuf.dump(serializer, this) fun <T : MessageMicro> T.toByteArray(serializer: SerializationStrategy<T>): ByteArray = ProtoBufWithNullableSupport.dump(serializer, this)
\ No newline at end of file \ No newline at end of file
...@@ -62,7 +62,8 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf( ...@@ -62,7 +62,8 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
OnlinePush.PbPushGroupMsg, OnlinePush.PbPushGroupMsg,
MessageSvc.PushNotify, MessageSvc.PushNotify,
MessageSvc.PbGetMsg, MessageSvc.PbGetMsg,
MessageSvc.PushForceOffline MessageSvc.PushForceOffline,
MessageSvc.PbSendMsg
) { ) {
// SvcReqMSFLoginNotify 自己的其他设备上限 // SvcReqMSFLoginNotify 自己的其他设备上限
// MessageSvc.PushReaded 电脑阅读了别人的消息, 告知手机 // MessageSvc.PushReaded 电脑阅读了别人的消息, 告知手机
......
...@@ -2,7 +2,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image ...@@ -2,7 +2,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.qqandroid.QQAndroidBot import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.network.QQAndroidClient import net.mamoe.mirai.qqandroid.network.QQAndroidClient
...@@ -19,7 +19,7 @@ internal object ImageDownPacket : PacketFactory<ImageDownPacket.ImageDownPacketR ...@@ -19,7 +19,7 @@ internal object ImageDownPacket : PacketFactory<ImageDownPacket.ImageDownPacketR
// TODO: 2020/1/24 测试: bodyType, subAppId // TODO: 2020/1/24 测试: bodyType, subAppId
return buildLoginOutgoingPacket(client, key = client.wLoginSigInfo.d2Key, bodyType = 1) { return buildLoginOutgoingPacket(client, key = client.wLoginSigInfo.d2Key, bodyType = 1) {
writeSsoPacket(client, subAppId = 0, commandName = commandName, sequenceId = it) { writeSsoPacket(client, subAppId = 0, commandName = commandName, sequenceId = it) {
val data = ProtoBuf.dump( val data = ProtoBufWithNullableSupport.dump(
Cmd0x352Packet.serializer(), Cmd0x352Packet.serializer(),
Cmd0x352Packet.createByImageRequest(req) Cmd0x352Packet.createByImageRequest(req)
) )
......
...@@ -2,7 +2,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image ...@@ -2,7 +2,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.qqandroid.QQAndroidBot import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.network.QQAndroidClient import net.mamoe.mirai.qqandroid.network.QQAndroidClient
...@@ -19,7 +19,7 @@ internal object ImageUpPacket : PacketFactory<ImageUpPacket.ImageUpPacketRespons ...@@ -19,7 +19,7 @@ internal object ImageUpPacket : PacketFactory<ImageUpPacket.ImageUpPacketRespons
// TODO: 2020/1/24 测试: bodyType, subAppId // TODO: 2020/1/24 测试: bodyType, subAppId
return buildLoginOutgoingPacket(client, key = client.wLoginSigInfo.d2Key, bodyType = 1) { return buildLoginOutgoingPacket(client, key = client.wLoginSigInfo.d2Key, bodyType = 1) {
writeSsoPacket(client, subAppId = 0, commandName = ImageDownPacket.commandName, sequenceId = it) { writeSsoPacket(client, subAppId = 0, commandName = ImageDownPacket.commandName, sequenceId = it) {
val data = ProtoBuf.dump( val data = ProtoBufWithNullableSupport.dump(
Cmd0x352Packet.serializer(), Cmd0x352Packet.serializer(),
Cmd0x352Packet.createByImageRequest(req) Cmd0x352Packet.createByImageRequest(req)
) )
......
...@@ -2,8 +2,11 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive ...@@ -2,8 +2,11 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.writeFully
import net.mamoe.mirai.data.MultiPacket import net.mamoe.mirai.data.MultiPacket
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.message.FriendMessage import net.mamoe.mirai.message.FriendMessage
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.qqandroid.QQAndroidBot import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.event.ForceOfflineEvent import net.mamoe.mirai.qqandroid.event.ForceOfflineEvent
import net.mamoe.mirai.qqandroid.io.readRemainingAsProtoBuf import net.mamoe.mirai.qqandroid.io.readRemainingAsProtoBuf
...@@ -12,18 +15,23 @@ import net.mamoe.mirai.qqandroid.io.writeProtoBuf ...@@ -12,18 +15,23 @@ import net.mamoe.mirai.qqandroid.io.writeProtoBuf
import net.mamoe.mirai.qqandroid.network.QQAndroidClient import net.mamoe.mirai.qqandroid.network.QQAndroidClient
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPushForceOffline import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPushForceOffline
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPushNotify import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPushNotify
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgComm
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
import net.mamoe.mirai.qqandroid.utils.toMessageChain import net.mamoe.mirai.qqandroid.utils.toMessageChain
import net.mamoe.mirai.qqandroid.utils.toRichTextElems
import net.mamoe.mirai.utils.cryptor.contentToString import net.mamoe.mirai.utils.cryptor.contentToString
import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.hexToBytes
import net.mamoe.mirai.utils.io.toReadPacket import net.mamoe.mirai.utils.io.toReadPacket
import kotlin.math.absoluteValue
import kotlin.random.Random
class MessageSvc { class MessageSvc {
/** /**
* 告知要刷新消息 * 告知要刷新好友消息
*/ */
internal object PushNotify : PacketFactory<RequestPushNotify>("MessageSvc.PushNotify") { internal object PushNotify : PacketFactory<RequestPushNotify>("MessageSvc.PushNotify") {
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): RequestPushNotify { override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): RequestPushNotify {
...@@ -41,7 +49,7 @@ class MessageSvc { ...@@ -41,7 +49,7 @@ class MessageSvc {
/** /**
* 进行刷新消息 * 获取好友消息和消息记录
*/ */
internal object PbGetMsg : PacketFactory<MultiPacket<FriendMessage>>("MessageSvc.PbGetMsg") { internal object PbGetMsg : PacketFactory<MultiPacket<FriendMessage>>("MessageSvc.PbGetMsg") {
val EXTRA_DATA = val EXTRA_DATA =
...@@ -65,9 +73,10 @@ class MessageSvc { ...@@ -65,9 +73,10 @@ class MessageSvc {
onlineSyncFlag = 1, onlineSyncFlag = 1,
// serverBuf = from.serverBuf ?: EMPTY_BYTE_ARRAY, // serverBuf = from.serverBuf ?: EMPTY_BYTE_ARRAY,
syncCookie = client.c2cMessageSync.syncCookie, syncCookie = client.c2cMessageSync.syncCookie,
syncFlag = client.c2cMessageSync.syncFlag, syncFlag = 1
msgCtrlBuf = client.c2cMessageSync.msgCtrlBuf, // syncFlag = client.c2cMessageSync.syncFlag,
pubaccountCookie = client.c2cMessageSync.pubAccountCookie //msgCtrlBuf = client.c2cMessageSync.msgCtrlBuf,
//pubaccountCookie = client.c2cMessageSync.pubAccountCookie
) )
) )
} }
...@@ -112,5 +121,43 @@ class MessageSvc { ...@@ -112,5 +121,43 @@ class MessageSvc {
return ForceOfflineEvent(bot, title = struct.title ?: "", tips = struct.tips ?: "") return ForceOfflineEvent(bot, title = struct.title ?: "", tips = struct.tips ?: "")
} }
} }
internal object PbSendMsg : PacketFactory<MsgSvc.PbSendMsgResp>("MessageSvc.PbSendMsg") {
object Response : Packet
/**
* 发送好友消息
*/
fun ToFriend(
client: QQAndroidClient,
toUin: Long,
message: MessageChain
): OutgoingPacket = buildOutgoingUniPacket(client) {
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
///return@buildOutgoingUniPacket
writeProtoBuf(
MsgSvc.PbSendMsgReq.serializer(), MsgSvc.PbSendMsgReq(
routingHead = MsgSvc.RoutingHead(c2c = MsgSvc.C2C(toUin = toUin)),
contentHead = MsgComm.ContentHead(pkgNum = 1),
msgBody = ImMsgBody.MsgBody(
richText = ImMsgBody.RichText(
elems = message.toRichTextElems()
)
),
msgSeq = 17041,
msgRand = Random.nextInt().absoluteValue,
syncCookie = client.c2cMessageSync.syncCookie.takeIf { it.isNotEmpty() } ?: "08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00".hexToBytes(),
msgVia = 1
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): MsgSvc.PbSendMsgResp {
discardExact(4)
return readRemainingAsProtoBuf(MsgSvc.PbSendMsgResp.serializer())
}
}
} }
...@@ -5,10 +5,11 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive ...@@ -5,10 +5,11 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.readBytes import kotlinx.io.core.readBytes
import kotlinx.serialization.protobuf.ProtoBuf
import net.mamoe.mirai.contact.MemberPermission import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.message.GroupMessage import net.mamoe.mirai.message.GroupMessage
import net.mamoe.mirai.qqandroid.QQAndroidBot import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgOnlinePush import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgOnlinePush
import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
...@@ -24,7 +25,7 @@ internal class OnlinePush { ...@@ -24,7 +25,7 @@ internal class OnlinePush {
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): GroupMessage { override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): GroupMessage {
// 00 00 02 E4 0A D5 05 0A 4F 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 52 20 00 28 BC 3D 30 8C 82 AB F1 05 38 D2 80 E0 8C 80 80 80 80 02 4A 21 08 E7 C1 AD B8 02 10 01 18 BA 05 22 09 48 69 6D 31 38 38 6D 6F 65 30 06 38 02 42 05 4D 69 72 61 69 50 01 58 01 60 00 88 01 08 12 06 08 01 10 00 18 00 1A F9 04 0A F6 04 0A 26 08 00 10 87 82 AB F1 05 18 B7 B4 BF 30 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 E6 03 42 E3 03 12 2A 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 22 00 2A 04 03 00 00 00 32 60 15 36 20 39 36 6B 45 31 41 38 35 32 32 39 64 63 36 39 38 34 37 39 37 37 62 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 31 32 31 32 41 38 C6 BB 8A A9 08 40 FB AE 9E C2 09 48 50 50 41 5A 00 60 01 6A 10 4E 18 58 22 0E 7B F8 0F C5 B1 34 48 83 74 D3 9C 72 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 31 39 38 3F 74 65 72 6D 3D 32 82 01 57 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 30 3F 74 65 72 6D 3D 32 B0 01 4D B8 01 2E C8 01 FF 05 D8 01 4D E0 01 2E FA 01 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 34 30 30 3F 74 65 72 6D 3D 32 80 02 4D 88 02 2E 12 45 AA 02 42 50 03 60 00 68 00 9A 01 39 08 09 20 BF 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 04 08 02 08 01 90 04 80 80 80 10 B8 04 00 C0 04 00 12 06 4A 04 08 00 40 01 12 14 82 01 11 0A 09 48 69 6D 31 38 38 6D 6F 65 18 06 20 08 28 03 10 8A CA 9D A1 07 1A 00 // 00 00 02 E4 0A D5 05 0A 4F 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 52 20 00 28 BC 3D 30 8C 82 AB F1 05 38 D2 80 E0 8C 80 80 80 80 02 4A 21 08 E7 C1 AD B8 02 10 01 18 BA 05 22 09 48 69 6D 31 38 38 6D 6F 65 30 06 38 02 42 05 4D 69 72 61 69 50 01 58 01 60 00 88 01 08 12 06 08 01 10 00 18 00 1A F9 04 0A F6 04 0A 26 08 00 10 87 82 AB F1 05 18 B7 B4 BF 30 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 E6 03 42 E3 03 12 2A 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 22 00 2A 04 03 00 00 00 32 60 15 36 20 39 36 6B 45 31 41 38 35 32 32 39 64 63 36 39 38 34 37 39 37 37 62 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 31 32 31 32 41 38 C6 BB 8A A9 08 40 FB AE 9E C2 09 48 50 50 41 5A 00 60 01 6A 10 4E 18 58 22 0E 7B F8 0F C5 B1 34 48 83 74 D3 9C 72 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 31 39 38 3F 74 65 72 6D 3D 32 82 01 57 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 30 3F 74 65 72 6D 3D 32 B0 01 4D B8 01 2E C8 01 FF 05 D8 01 4D E0 01 2E FA 01 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 34 30 30 3F 74 65 72 6D 3D 32 80 02 4D 88 02 2E 12 45 AA 02 42 50 03 60 00 68 00 9A 01 39 08 09 20 BF 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 04 08 02 08 01 90 04 80 80 80 10 B8 04 00 C0 04 00 12 06 4A 04 08 00 40 01 12 14 82 01 11 0A 09 48 69 6D 31 38 38 6D 6F 65 18 06 20 08 28 03 10 8A CA 9D A1 07 1A 00
discardExact(4) discardExact(4)
val pbPushMsg = ProtoBuf.load(MsgOnlinePush.PbPushMsg.serializer(), readBytes()) val pbPushMsg = ProtoBufWithNullableSupport.load(MsgOnlinePush.PbPushMsg.serializer(), readBytes())
val extraInfo: ImMsgBody.ExtraInfo? = pbPushMsg.msg.msgBody.richText.elems.firstOrNull { it.extraInfo != null }?.extraInfo val extraInfo: ImMsgBody.ExtraInfo? = pbPushMsg.msg.msgBody.richText.elems.firstOrNull { it.extraInfo != null }?.extraInfo
...@@ -48,5 +49,11 @@ internal class OnlinePush { ...@@ -48,5 +49,11 @@ internal class OnlinePush {
} }
) )
} }
override suspend fun QQAndroidBot.handle(packet: GroupMessage) {
if (packet.senderName == "Him188moe") {
this.getQQ(2978594313).sendMessage("FROM MIRAI")
}
}
} }
} }
\ No newline at end of file
...@@ -267,9 +267,7 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt ...@@ -267,9 +267,7 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt
sealed class LoginPacketResponse : Packet { sealed class LoginPacketResponse : Packet {
object Success : LoginPacketResponse() { object Success : LoginPacketResponse() {
override fun toString(): String { override fun toString(): String = "LoginPacketResponse.Success"
return "LoginPacketResponse.Success"
}
} }
data class Error( data class Error(
...@@ -283,18 +281,22 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt ...@@ -283,18 +281,22 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt
class Slider( class Slider(
val url: String val url: String
) : Captcha() { ) : Captcha() {
override fun toString(): String { override fun toString(): String = "LoginPacketResponse.Captcha.Slider"
return "LoginPacketResponse.Captcha.Slider"
}
} }
class Picture( class Picture(
val data: IoBuffer, val data: IoBuffer,
val sign: ByteArray val sign: ByteArray
) : Captcha() { ) : Captcha() {
override fun toString(): String { override fun toString(): String = "LoginPacketResponse.Captcha.Picture"
return "LoginPacketResponse.Captcha.Picture" }
} }
data class UnsafeLogin(val url: String) : LoginPacketResponse()
class SMSVerifyCodeNeeded(val t402: ByteArray, val t403: ByteArray) : LoginPacketResponse(){
override fun toString(): String {
return "LoginPacketResponse.SMSVerifyCodeNeeded"
} }
} }
......
package net.mamoe.mirai.qqandroid.network.protocol.packet.login package net.mamoe.mirai.qqandroid.network.protocol.packet.login
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.qqandroid.QQAndroidBot import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.io.serialization.toByteArray import net.mamoe.mirai.qqandroid.io.serialization.toByteArray
...@@ -103,7 +103,7 @@ class StatSvc { ...@@ -103,7 +103,7 @@ class StatSvc {
var44.strVendorName = ROMUtil.getRomName(); var44.strVendorName = ROMUtil.getRomName();
var44.strVendorOSName = ROMUtil.getRomVersion(20); var44.strVendorOSName = ROMUtil.getRomVersion(20);
*/ */
bytes_0x769_reqbody = ProtoBuf.dump( bytes_0x769_reqbody = ProtoBufWithNullableSupport.dump(
Oidb0x769.RequestBody.serializer(), Oidb0x769.RequestBody( Oidb0x769.RequestBody.serializer(), Oidb0x769.RequestBody(
rpt_config_list = listOf( rpt_config_list = listOf(
Oidb0x769.ConfigSeq( Oidb0x769.ConfigSeq(
......
...@@ -2,7 +2,7 @@ package net.mamoe.mirai.qqandroid.utils ...@@ -2,7 +2,7 @@ package net.mamoe.mirai.qqandroid.utils
import kotlinx.serialization.SerialId import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import net.mamoe.mirai.utils.cryptor.contentToString import net.mamoe.mirai.utils.cryptor.contentToString
import net.mamoe.mirai.utils.getValue import net.mamoe.mirai.utils.getValue
import net.mamoe.mirai.utils.unsafeWeakRef import net.mamoe.mirai.utils.unsafeWeakRef
...@@ -62,7 +62,7 @@ abstract class DeviceInfo( ...@@ -62,7 +62,7 @@ abstract class DeviceInfo(
@SerialId(9) val innerVersion: ByteArray @SerialId(9) val innerVersion: ByteArray
) )
return ProtoBuf.dump( return ProtoBufWithNullableSupport.dump(
DevInfo.serializer(), DevInfo( DevInfo.serializer(), DevInfo(
bootloader, bootloader,
procVersion, procVersion,
......
...@@ -3,16 +3,15 @@ package net.mamoe.mirai.qqandroid.utils ...@@ -3,16 +3,15 @@ package net.mamoe.mirai.qqandroid.utils
import net.mamoe.mirai.data.ImageLink import net.mamoe.mirai.data.ImageLink
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
internal fun MessageChain.constructPbSendMsgReq(): MsgSvc.PbSendMsgReq { internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> {
val request = MsgSvc.PbSendMsgReq() val elems = mutableListOf<ImMsgBody.Elem>()
this.forEach { this.forEach {
when (it) { when (it) {
is PlainText -> { is PlainText -> {
request.msgBody.richText.elems.add(ImMsgBody.Elem(text = ImMsgBody.Text(str = it.stringValue))) elems.add(ImMsgBody.Elem(text = ImMsgBody.Text(str = it.stringValue)))
} }
is At -> { is At -> {
...@@ -20,8 +19,7 @@ internal fun MessageChain.constructPbSendMsgReq(): MsgSvc.PbSendMsgReq { ...@@ -20,8 +19,7 @@ internal fun MessageChain.constructPbSendMsgReq(): MsgSvc.PbSendMsgReq {
} }
} }
return elems
return request
} }
......
...@@ -7,7 +7,6 @@ import kotlinx.serialization.SerializationStrategy ...@@ -7,7 +7,6 @@ import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.cryptor.encryptAndWrite import net.mamoe.mirai.utils.cryptor.encryptAndWrite
import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.hexToBytes
......
...@@ -200,9 +200,9 @@ fun Any?.contentToString(prefix: String = ""): String = when (this) { ...@@ -200,9 +200,9 @@ fun Any?.contentToString(prefix: String = ""): String = when (this) {
} }
is ProtoMap -> "ProtoMap(size=$size){\n" + this.toStringPrefixed("$prefix${ProtoMap.indent}${ProtoMap.indent}") + "\n$prefix${ProtoMap.indent}}" is ProtoMap -> "ProtoMap(size=$size){\n" + this.toStringPrefixed("$prefix${ProtoMap.indent}${ProtoMap.indent}") + "\n$prefix${ProtoMap.indent}}"
is Iterable<*> -> this.joinToString(prefix = "[", postfix = "]") { it.contentToString() } is Iterable<*> -> this.joinToString(prefix = "[", postfix = "]") { it.contentToString(prefix) }
is Iterator<*> -> this.asSequence().joinToString(prefix = "[", postfix = "]") { it.contentToString() } is Iterator<*> -> this.asSequence().joinToString(prefix = "[", postfix = "]") { it.contentToString(prefix) }
is Sequence<*> -> this.joinToString(prefix = "[", postfix = "]") { it.contentToString() } is Sequence<*> -> this.joinToString(prefix = "[", postfix = "]") { it.contentToString(prefix) }
is Map<*, *> -> this.entries.joinToString(prefix = "{", postfix = "}") { it.key.contentToString(prefix) + "=" + it.value.contentToString(prefix) } is Map<*, *> -> this.entries.joinToString(prefix = "{", postfix = "}") { it.key.contentToString(prefix) + "=" + it.value.contentToString(prefix) }
else -> { else -> {
if (this == null) "null" if (this == null) "null"
......
package test
import net.mamoe.mirai.utils.io.hexToBytes
import net.mamoe.mirai.utils.io.read
import net.mamoe.mirai.utils.io.readTLVMap
import net.mamoe.mirai.utils.io.toUHexString
@ExperimentalStdlibApi
@Suppress("EXPERIMENTAL_API_USAGE")
fun main() {
val newMap =
"4E 22 00 03 E5 AE 89 4E 25 00 06 35 31 31 34 39 35 4E 26 00 01 2D 4E 27 00 01 2D 4E 29 00 01 02 4E 2A 00 06 56 69 76 69 61 6E 4E 2B 00 10 31 35 36 31 34 38 39 31 33 40 71 71 2E 63 6F 6D 4E 2D 00 1D 68 74 74 70 3A 2F 2F 31 35 36 31 34 38 39 31 33 2E 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 4E 2E 00 02 33 00 4E 2F 00 04 33 33 39 00 4E 30 00 01 2D 4E 31 00 01 00 4E 33 00 2D E6 88 91 E7 95 99 E9 95 BF E7 9A 84 E5 A4 B4 E5 8F 91 EF BC 8C E6 98 AF E4 BD A0 E9 94 99 E8 BF 87 E7 9A 84 E5 B9 B4 E5 8D 8E 2E 2E 2E 4E 35 00 18 E5 B9 BF E4 B8 9C E6 8A 80 E6 9C AF E5 B8 88 E8 8C 83 E5 AD A6 E9 99 A2 4E 36 00 01 0A 4E 37 00 01 03 4E 38 00 01 01 4E 3F 00 04 07 C2 0B 02 4E 40 00 0C 00 00 00 31 00 00 34 34 00 00 00 33 4E 41 00 02 00 00 4E 42 00 02 00 00 4E 43 00 02 00 00 4E 45 00 01 21 4E 49 00 04 00 00 00 00 4E 4B 00 04 00 00 00 00 4E 4F 00 01 00 4E 54 00 00 4E 5B 00 00 52 0B 00 04 13 88 02 02 52 0F 00 14 00 00 00 00 00 00 00 00 12 05 10 58 89 10 00 00 00 00 00 00 5D C2 00 0C 00 00 00 31 00 00 34 34 00 00 31 34 5D C8 00 1E E7 B4 A2 E5 B0 BC EF BC 88 E4 B8 AD E5 9B BD EF BC 89 E6 9C 89 E9 99 90 E5 85 AC E5 8F B8 65 97 00 01 11 69 9D 00 04 00 00 00 00 69 A9 00 00 9D A5 00 02 00 00 A4 91 00 02 00 00 A4 93 00 02 00 00 A4 94 00 02 00 00 A4 9C 00 02 00 00 A4 B5 00 02 00 00"
.hexToBytes().read {
readTLVMap(tagSize = 2, expectingEOF = true)
}
newMap.forEach { (key, value) ->
if (!(value.isEmpty() || value.all { it.toInt() == 0 })) {
println(key.toUShort().toUHexString() + "=" + value.decodeToString())
}
}
return
}
\ No newline at end of file
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
package test
import kotlinx.serialization.ImplicitReflectionSerializer
import kotlinx.serialization.SerialId
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoBuf
import kotlinx.serialization.protobuf.ProtoNumberType
import kotlinx.serialization.protobuf.ProtoType
import kotlinx.serialization.serializer
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.cryptor.readProtoMap
import net.mamoe.mirai.utils.io.hexToBytes
import net.mamoe.mirai.utils.io.read
import kotlin.reflect.KClass
@Serializable
data class ProtoTest(
//@SerialId(1) val string: String,
//@SerialId(1) val int: Int,
//@SerialId(1) val boolean: Boolean,
//@SerialId(1) val short: Short,
//@SerialId(1) val byte: Byte,
@SerialId(1) @ProtoType(ProtoNumberType.FIXED) val fixedByte: Byte
)
@UseExperimental(MiraiInternalAPI::class)
suspend fun main() {
deserializeTest()
}
suspend fun deserializeTest() {
val bytes =
"""
08 02 1A 55 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 1A 25 2F 34 35 35 38 66 39 30 38 2D 37 62 39 61 2D 34 65 32 66 2D 38 63 36 39 2D 34 61 35 32 61 66 62 33 36 35 61 37 20 01 30 04 38 05 40 09 48 01 58 00 60 01 6A 0A 38 2E 32 2E 30 2E 31 32 39 36 70 E0 8C B2 F0 05 78 01 50 03
""".trimIndent()
.replace("\n", " ")
.replace("UVarInt", "", ignoreCase = true)
.replace("uint", "", ignoreCase = true)
.replace("[", "")
.replace("]", "")
.replace("(", "")
.replace(")", "")
.replace(" ", " ")
.replace(" ", " ")
.replace(" ", " ")
.replace("_", "")
.replace(",", "")
.hexToBytes()
println(bytes.read { readProtoMap() })
}
@UseExperimental(ImplicitReflectionSerializer::class)
fun <T : Any> KClass<T>.loadFrom(protoBuf: ByteArray): T = ProtoBuf.load(this.serializer(), protoBuf)
\ No newline at end of file
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