From dcdee6b8477bb70478812d176dfe59ec2b65a9ff Mon Sep 17 00:00:00 2001 From: Him188 Date: Mon, 25 Nov 2019 18:00:07 +0800 Subject: [PATCH] At supported --- .../kotlin/net.mamoe.mirai/message/Message.kt | 4 +-- .../net.mamoe.mirai/message/MessageType.kt | 2 +- .../message/internal/MessageDataInternal.kt | 33 ++++++++++++++----- .../protocol/tim/packet/event/Ignored.kt | 3 +- .../src/main/kotlin/demo/gentleman/Main.kt | 3 ++ 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt index e42649477..7b643e087 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt @@ -218,10 +218,10 @@ suspend inline fun ImageId.sendTo(contact: Contact) = contact.sendMessage(this.i /** * At 一个人 */ -inline class At(val targetQQ: UInt) : Message { +inline class At(val target: UInt) : Message { constructor(target: QQ) : this(target.id) - override val stringValue: String get() = "[@$targetQQ]" + override val stringValue: String get() = "[@$target]" // TODO: 2019/11/25 使用群名称进行 at. 因为手机端只会显示这个文字 override fun toString(): String = stringValue companion object Key : Message.Key diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageType.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageType.kt index 7e0edd76e..55386e16d 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageType.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageType.kt @@ -6,7 +6,7 @@ package net.mamoe.mirai.message @Suppress("unused") enum class MessageType(val value: UByte) { PLAIN_TEXT(0x01u), - AT(0x06u), + AT(0x01u), // same as PLAIN FACE(0x02u), /** * [ImageId.value] 长度为 42 的图片 diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt index 7496fcf69..32c6b83ab 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt @@ -18,9 +18,16 @@ internal fun IoBuffer.parseMessageFace(): Face { return Face(id1) } -internal fun IoBuffer.parsePlainText(): PlainText { - discardExact(1)//0x01 - return PlainText(readUShortLVString()) +internal fun IoBuffer.parsePlainTextOrAt(): Message { + // 06 00 0D 00 01 00 00 00 08 00 76 E4 B8 DD 00 00 + discardExact(1)// 0x01 whenever plain or at + val msg = readUShortLVString() + return if (this.readRemaining == 0) { + PlainText(msg) + } else { + discardExact(10) + At(readUInt()) + } } internal fun IoBuffer.parseLongText0x19(): PlainText { @@ -59,7 +66,7 @@ internal fun IoBuffer.parseMessageImage0x06(): Image { internal fun IoBuffer.parseMessageImage0x03(): Image { //discardExact(1) val tlv = readTLVMap(expectingEOF = true, tagSize = 1) - tlv.printTLVMap("parseMessageImage0x03") + //tlv.printTLVMap("parseMessageImage0x03") // 02 [ ] IMAGE ID // 04 [00 04] 8B 88 95 C1 // 05 [00 04] 3B 24 59 FC @@ -85,7 +92,7 @@ internal fun IoBuffer.parseMessageImage0x03(): Image { uniqueId = tlv[0x04u]!!.read { readUInt() }, height = tlv[0x16u]!!.toUInt().toInt(), width = tlv[0x15u]!!.toUInt().toInt() - ).also { debugPrintln("ImageId: $it") } + )//.also { debugPrintln("ImageId: $it") } ) //} else { // Image( @@ -113,8 +120,7 @@ internal fun ByteReadPacket.readMessage(): Message? { return try { when (messageType) { - //todo 在每个parse里面都 discard 了第一 byte. - 0x01 -> sectionData.parsePlainText() + 0x01 -> sectionData.parsePlainTextOrAt() 0x02 -> sectionData.parseMessageFace() 0x03 -> sectionData.parseMessageImage0x03() 0x06 -> sectionData.parseMessageImage0x06() @@ -196,7 +202,18 @@ fun MessageChain.toPacket(): ByteReadPacket = buildPacket { } } - is At -> throw UnsupportedOperationException("At is not supported now but is expecting to be supported") + is At -> buildPacket { + writeUByte(MessageType.AT.value) + + writeShortLVPacket { + writeByte(0x01) + writeShortLVString(stringValue) // 这个应该是 "@群名", 手机上面会显示这个消息, 电脑会显示下面那个 + // 06 00 0D 00 01 00 00 00 08 00 76 E4 B8 DD 00 00 + writeHex("06 00 0D 00 01 00 00 00 08 00") + writeUInt(target) + writeZero(2) + } + } is Image -> buildPacket { when (id.value.length) { diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Ignored.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Ignored.kt index 8224d8fc9..4754659a9 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Ignored.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Ignored.kt @@ -4,9 +4,10 @@ package net.mamoe.mirai.network.protocol.tim.packet.event import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.Bot +import net.mamoe.mirai.utils.io.toUHexString inline class IgnoredEventPacket(val id: UShort) : EventPacket { - override fun toString(): String = "IgnoredEventPacket(id=$id)" + override fun toString(): String = "IgnoredEventPacket(id=0x${id.toUHexString("")})" } object IgnoredEventIds : List by { diff --git a/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt b/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt index ae01471da..85c21fc14 100644 --- a/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt +++ b/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt @@ -12,6 +12,7 @@ import net.mamoe.mirai.contact.MemberPermission import net.mamoe.mirai.event.Subscribable import net.mamoe.mirai.event.subscribeAlways import net.mamoe.mirai.event.subscribeMessages +import net.mamoe.mirai.message.At import net.mamoe.mirai.message.Image import net.mamoe.mirai.message.getValue import net.mamoe.mirai.message.sendAsImageTo @@ -60,6 +61,8 @@ suspend fun main() { } bot.subscribeMessages { + case("at me") { At(sender).reply() } + "你好" reply "你好!" startsWith("profile", removePrefix = true) {