From d3ccb56658f6173ddc576afd77efe4432f751598 Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 15 Nov 2019 10:32:16 +0800 Subject: [PATCH] Alter AnnotationTarget of CorrespondingEvent to SOURCE --- .../protocol/tim/packet/Annotations.kt | 2 +- .../protocol/tim/packet/action/GradeInfo.kt | 4 +- .../packet/action/SendGroupMessagePacket.kt | 5 +- .../protocol/tim/packet/action/UploadImage.kt | 220 ++++++++++++------ 4 files changed, 159 insertions(+), 72 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Annotations.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Annotations.kt index 2532c9bb1..d79f63635 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Annotations.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Annotations.kt @@ -25,7 +25,7 @@ inline val AnnotatedId.value: UShort get() = id.value * 这个注解应该被标记在 [Packet] 上 */ @MustBeDocumented -@Retention(AnnotationRetention.BINARY) +@Retention(AnnotationRetention.SOURCE) @Target(AnnotationTarget.CLASS) annotation class CorrespondingEvent( val eventClass: KClass diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt index 6f6fef729..6a8c56bc3 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt @@ -3,12 +3,12 @@ package net.mamoe.mirai.network.protocol.tim.packet.action import kotlinx.io.core.ByteReadPacket +import kotlinx.io.core.writeFully import kotlinx.io.core.writeUByte import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.packet.* import net.mamoe.mirai.utils.io.encryptAndWrite -import net.mamoe.mirai.utils.io.writeHex import net.mamoe.mirai.utils.io.writeQQ /** @@ -23,7 +23,7 @@ object RequestAccountInfoPacket : SessionPacketFactory(url).readBytes() // TODO 不知道为什么找不到 `ByteReadChannel`. + /* /** * 似乎没有必要. 服务器的返回永远都是 01 00 00 00 02 00 00 */ @Deprecated("Useless packet") @AnnotatedId(KnownPacketId.SUBMIT_IMAGE_FILE_NAME) -@PacketVersion(date = "2019.10.26", timVersion = "2.3.2.21173") +@PacketVersion(date = "2019.10.26", timVersion = "2.3.2 (21173)") object SubmitImageFilenamePacket : PacketFactory { operator fun invoke( bot: UInt, @@ -140,7 +152,7 @@ object SubmitImageFilenamePacket : PacketFactory { sessionKey: SessionKey ): OutgoingPacket = buildOutgoingPacket { writeQQ(bot) - writeHex(TIMProtocol.fixVer2)//? + writeFully(TIMProtocol.fixVer2)//? //writeHex("04 00 00 00 01 2E 01 00 00 69 35") encryptAndWrite(sessionKey) { @@ -166,7 +178,7 @@ object SubmitImageFilenamePacket : PacketFactory { //解密body=01 3E 03 3F A2 7C BC D3 C1 00 00 27 1C 00 0A 00 01 00 01 00 30 55 73 65 72 44 61 74 61 43 75 73 74 6F 6D 46 61 63 65 3A 31 5C 29 37 42 53 4B 48 32 44 35 54 51 28 5A 35 7D 35 24 56 5D 32 35 49 4E 2E 6A 70 67 00 00 03 73 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 2F 02 } - @PacketVersion(date = "2019.10.19", timVersion = "2.3.2.21173") + @PacketVersion(date = "2019.10.19", timVersion = "2.3.2 (21173)") class Response { override fun decode() = with(input) { require(readBytes().contentEquals(expecting)) @@ -178,6 +190,101 @@ object SubmitImageFilenamePacket : PacketFactory { } }*/ +/** + * 通过 [ImageId] 请求下载链接. + */ +@AnnotatedId(KnownPacketId.FRIEND_IMAGE_ID) +@PacketVersion(date = "2019.11.14", timVersion = "2.3.2 (21173)") +object FriendImageIdDownloadLinkRequestPacket : SessionPacketFactory() { + operator fun invoke( + bot: UInt, + sessionKey: SessionKey, + target: UInt, + imageId: ImageId + ): OutgoingPacket { + imageId.requireLength() + + // 00 00 00 07 00 00 00 + // [4B] + // 08 + // 01 12 + // 03 98 + // 01 02 + // 08 02 + // + // 1A [47] + // 08 [A2 FF 8C F0 03] UVarInt + // 10 [DD F1 92 B7 07] UVarInt + // 1A [25] 2F 38 65 32 63 32 38 62 64 2D 35 38 61 31 2D 34 66 37 30 2D 38 39 61 31 2D 65 37 31 39 66 63 33 30 37 65 65 66 + // 20 02 30 04 38 20 40 FF 01 50 00 6A 05 32 36 39 33 33 78 01 + + return buildSessionPacket(bot, sessionKey, version = TIMProtocol.version0x04) { + writeHex("00 00 00 07 00 00") + + writeShortLVPacket(lengthOffset = { it - 7 }) { + writeUByte(0x08u) + writeTV(0x01_12u) + writeTV(0x03_98u) + writeTV(0x01_02u) + writeTV(0x08_02u) + writeTV(0x1A_47u) + writeTUVarint(0x08u, bot) + writeTUVarint(0x10u, target) + writeTLV(0x1Au, imageId.value.toByteArray()) + writeHex("20 02 30 04 38 20 40 FF 01 50 00 6A 05 32 36 39 33 33 78 01") + } + } + } + + /** + * 图片下载链接. 直接 'get' 请求即可 + */ + data class DownloadLink( + val imageId: ImageId, + val link: String + ) : Packet + + // TODO: 2019/11/14 需要跟 RequestId packet 合并. 因为现行结构无法分别处理; 或者考虑修改结构(不推荐) + + override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): DownloadLink { + //00 00 00 08 00 00 + // [02 2B] + // 12 [06] 98 01 02 A0 01 00 + // 08 02 1A + // [A6 04] + // 0A [25] 2F 38 65 32 63 32 38 62 64 2D 35 38 61 31 2D 34 66 37 30 2D 38 39 61 31 2D 65 37 31 39 66 63 33 30 37 65 65 66 + // 18 00 32 + // [7B] 68 74 74 70 3A 2F 2F 36 31 2E 31 35 31 2E 32 33 34 2E 35 34 3A 38 30 2F 6F 66 66 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 2F 38 65 32 63 32 38 62 64 2D 35 38 61 31 2D 34 66 37 30 2D 38 39 61 31 2D 65 37 31 39 66 63 33 30 37 65 65 66 2F 30 3F 76 75 69 6E 3D 31 30 34 30 34 30 30 32 39 30 26 74 65 72 6D 3D 32 35 35 26 73 72 76 76 65 72 3D 32 36 39 33 33 32 7C 68 74 74 70 3A 2F 2F 31 30 31 2E 32 32 37 2E 31 33 31 2E 36 37 3A 38 30 2F 6F 66 66 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 2F 38 65 32 63 32 38 62 64 2D 35 38 61 31 2D 34 66 37 30 2D 38 39 61 31 2D 65 37 31 39 66 63 33 30 37 65 65 66 2F 30 3F 76 75 69 6E 3D 31 30 34 30 34 30 30 32 39 30 26 74 65 72 6D 3D 32 35 35 26 73 72 76 76 65 72 3D 32 36 39 33 33 32 7D 68 74 74 70 3A 2F 2F 31 35 37 2E 32 35 35 2E 31 39 32 2E 31 30 35 3A 38 30 2F 6F 66 66 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 2F 38 65 32 63 32 38 62 64 2D 35 38 61 31 2D 34 66 37 30 2D 38 39 61 31 2D 65 37 31 39 66 63 33 30 37 65 65 66 2F 30 3F 76 75 69 6E 3D 31 30 34 30 34 30 30 32 39 30 26 74 65 72 6D 3D 32 35 35 26 73 72 76 76 65 72 3D 32 36 39 33 33 32 7C 68 74 74 70 3A 2F 2F 31 32 30 2E 32 34 31 2E 31 39 30 2E 34 31 3A 38 30 2F 6F 66 66 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 2F 38 65 32 63 32 38 62 64 2D 35 38 61 31 2D 34 66 37 30 2D 38 39 61 31 2D 65 37 31 39 66 63 33 30 37 65 65 66 2F 30 3F 76 75 69 6E 3D 31 30 34 30 34 30 30 32 39 30 26 74 65 72 6D 3D 32 35 35 26 73 72 76 76 65 72 3D 32 36 39 33 33 + // 3A 00 80 01 00 + + + //00 00 00 08 00 00 + // [02 29] + // 12 [06] 98 01 02 A0 01 00 + // 08 02 1A + // [A4 04] + // 0A [25] 2F 62 61 65 30 63 64 66 66 2D 65 33 34 30 2D 34 38 39 34 2D 39 37 36 65 2D 30 66 62 35 38 61 61 31 36 35 66 64 + // 18 00 32 + // [7A] 68 74 74 70 3A 2F 2F 31 30 31 2E 38 39 2E 33 39 2E 32 31 3A 38 30 2F 6F 66 66 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 2F 62 61 65 30 63 64 66 66 2D 65 33 34 30 2D 34 38 39 34 2D 39 37 36 65 2D 30 66 62 35 38 61 61 31 36 35 66 64 2F 30 3F 76 75 69 6E 3D 31 30 34 30 34 30 30 32 39 30 26 74 65 72 6D 3D 32 35 35 26 73 72 76 76 65 72 3D 32 36 39 33 33 + // 32 7B 68 74 74 70 3A 2F 2F 36 31 2E 31 35 31 2E 31 38 33 2E 32 31 3A 38 30 2F 6F 66 66 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 2F 62 61 65 30 63 64 66 66 2D 65 33 34 30 2D 34 38 39 34 2D 39 37 36 65 2D 30 66 62 35 38 61 61 31 36 35 66 64 2F 30 3F 76 75 69 6E 3D 31 30 34 30 34 30 30 32 39 30 26 74 65 72 6D 3D 32 35 35 26 73 72 76 76 65 72 3D 32 36 39 33 33 32 7D 68 74 74 70 3A 2F 2F 31 35 37 2E 32 35 35 2E 31 39 32 2E 31 30 35 3A 38 30 2F 6F 66 66 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 2F 62 61 65 30 63 64 66 66 2D 65 33 34 30 2D 34 38 39 34 2D 39 37 36 65 2D 30 66 62 35 38 61 61 31 36 35 66 64 2F 30 3F 76 75 69 6E 3D 31 30 34 30 34 30 30 32 39 30 26 74 65 72 6D 3D 32 35 35 26 73 72 76 76 65 72 3D 32 36 39 33 33 32 7C 68 74 74 70 3A 2F 2F 31 32 30 2E 32 34 31 2E 31 39 30 2E 34 31 3A 38 30 2F 6F 66 66 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 2F 62 61 65 30 63 64 66 66 2D 65 33 34 30 2D 34 38 39 34 2D 39 37 36 65 2D 30 66 62 35 38 61 61 31 36 35 66 64 2F 30 3F 76 75 69 6E 3D 31 30 34 30 34 30 30 32 39 30 26 74 65 72 6D 3D 32 35 35 26 73 72 76 76 65 72 3D 32 36 39 33 33 3A 00 80 01 00 + + discardExact(6)//00 00 00 08 00 00 + discardExact(2)// [02 29] + discardExact(1 + 1 + 6)// 12 [06] 98 01 02 A0 01 00 + discardExact(3)// 08 02 1A + + discardExact(2)// [A4 04] 后文长度 + check(readUByte().toUInt() == 0x0Au) { "Illegal identity. Required 0x0Au" } + val imageId = ImageId(readString(readUByte().toInt())) + + check(readUByte().toUInt() == 0x18u) { "Illegal identity. Required 0x18u" } + check(readUShort().toUInt() == 0x0032u) { "Illegal identity. Required 0x0032u" } + + val link = readUVarIntLVString() + discard() + return DownloadLink(imageId, link) + } +} /** * 请求上传图片. 将发送图片的 md5, size, width, height. @@ -186,72 +293,51 @@ object SubmitImageFilenamePacket : PacketFactory { * - 服务器未存有, 返回一个 key 用于客户端上传 */ @AnnotatedId(KnownPacketId.FRIEND_IMAGE_ID) -@PacketVersion(date = "2019.11.1", timVersion = "2.3.2.21173") +@PacketVersion(date = "2019.11.1", timVersion = "2.3.2 (21173)") object FriendImageIdRequestPacket : SessionPacketFactory() { operator fun invoke( bot: UInt, sessionKey: SessionKey, target: UInt, image: ExternalImage - ): OutgoingPacket = buildOutgoingPacket { - writeQQ(bot) - writeHex("04 00 00 00 01 2E 01 00 00 69 35 00 00 00 00 00 00 00 00") + ): OutgoingPacket = buildSessionPacket(bot, sessionKey, version = TIMProtocol.version0x04) { + writeHex("00 00 00 07 00 00") - encryptAndWrite(sessionKey) { - writeHex("00 00 00 07 00 00 00") + writeShortLVPacket(lengthOffset = { it - 7 }) { + writeUByte(0x08u) + writeTV(0x01_12u) + writeTV(0x03_98u) + writeTV(0x01_01u) + writeTV(0x08_01u) - writeUVarintLVPacket(lengthOffset = { it - 7 }) { - writeUByte(0x08u) - writeUShort(0x01_12u) - writeUShort(0x03_98u) - writeUShort(0x01_01u) - writeUShort(0x08_01u) - - writeUVarintLVPacket(tag = 0x12u, lengthOffset = { it + 1 }) { - writeUByte(0x08u) - writeUVarInt(bot) - - writeUByte(0x10u) - writeUVarInt(target) - - writeUShort(0x18_00u) - - writeUByte(0x22u) - writeUByte(0x10u) - writeFully(image.md5) - - writeUByte(0x28u) - writeUVarInt(image.inputSize.toUInt()) - - - writeUByte(0x32u) - //长度应为1A - writeUVarintLVPacket { - writeUShort(0x28_00u) - writeUShort(0x46_00u) - writeUShort(0x51_00u) - writeUShort(0x56_00u) - writeUShort(0x4B_00u) - writeUShort(0x41_00u) - writeUShort(0x49_00u) - writeUShort(0x25_00u) - writeUShort(0x4B_00u) - writeUShort(0x24_00u) - writeUShort(0x55_00u) - writeUShort(0x30_00u) - writeUShort(0x24_00u) - } - - writeUShort(0x38_01u) - writeUShort(0x48_00u) - - writeUByte(0x70u) - writeUVarInt(image.width.toUInt()) - writeUByte(0x78u) - writeUVarInt(image.height.toUInt()) + writeUVarIntLVPacket(tag = 0x12u, lengthOffset = { it + 1 }) { + writeTUVarint(0x08u, bot) + writeTUVarint(0x10u, target) + writeTV(0x18_00u) + writeTLV(0x22u, image.md5) + writeTUVarint(0x28u, image.inputSize.toUInt()) + writeUVarIntLVPacket(tag = 0x32u) { + writeTV(0x28_00u) + writeTV(0x46_00u) + writeTV(0x51_00u) + writeTV(0x56_00u) + writeTV(0x4B_00u) + writeTV(0x41_00u) + writeTV(0x49_00u) + writeTV(0x25_00u) + writeTV(0x4B_00u) + writeTV(0x24_00u) + writeTV(0x55_00u) + writeTV(0x30_00u) + writeTV(0x24_00u) } + writeTV(0x38_01u) + writeTV(0x48_00u) + writeTUVarint(0x70u, image.width.toUInt()) + writeTUVarint(0x78u, image.height.toUInt()) } } + } @@ -307,10 +393,10 @@ object FriendImageIdRequestPacket : SessionPacketFactory() { operator fun invoke( bot: UInt, @@ -343,13 +429,13 @@ object GroupImageIdRequestPacket : SessionPacketFactory