Alter AnnotationTarget of CorrespondingEvent to SOURCE

This commit is contained in:
Him188 2019-11-15 10:32:16 +08:00
parent ccfb4f085d
commit d3ccb56658
4 changed files with 159 additions and 72 deletions

View File

@ -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<out Subscribable>

View File

@ -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<RequestAccountInfoPacket.
sessionKey: SessionKey
): OutgoingPacket = buildOutgoingPacket {
writeQQ(qq)
writeHex(TIMProtocol.fixVer2)
writeFully(TIMProtocol.fixVer2)
encryptAndWrite(sessionKey) {
writeUByte(0x88u)
writeQQ(qq)

View File

@ -3,6 +3,7 @@
package net.mamoe.mirai.network.protocol.tim.packet.action
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.writeFully
import net.mamoe.mirai.contact.GroupInternalId
import net.mamoe.mirai.message.MessageChain
import net.mamoe.mirai.message.internal.toPacket
@ -19,7 +20,7 @@ object SendGroupMessagePacket : SessionPacketFactory<SendGroupMessagePacket.Resp
message: MessageChain
): OutgoingPacket = buildOutgoingPacket {
writeQQ(botQQ)
writeHex(TIMProtocol.fixVer2)
writeFully(TIMProtocol.fixVer2)
encryptAndWrite(sessionKey) {
writeByte(0x2A)
@ -32,7 +33,7 @@ object SendGroupMessagePacket : SessionPacketFactory<SendGroupMessagePacket.Resp
writeTime()
writeRandom(4)
writeHex("00 00 00 00 09 00 86")
writeHex(TIMProtocol.messageConst1)
writeFully(TIMProtocol.messageConst1)
writeZero(2)
writePacket(message.toPacket())

View File

@ -1,9 +1,12 @@
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS", "unused")
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS", "unused", "NO_REFLECTION_IN_CLASS_PATH")
package net.mamoe.mirai.network.protocol.tim.packet.action
import io.ktor.client.HttpClient
import io.ktor.client.request.get
import io.ktor.client.request.post
import io.ktor.client.response.HttpResponse
import io.ktor.client.response.readBytes
import io.ktor.http.HttpStatusCode
import io.ktor.http.URLProtocol
import io.ktor.http.userAgent
@ -11,12 +14,16 @@ import kotlinx.coroutines.withContext
import kotlinx.io.core.*
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.message.ImageId
import net.mamoe.mirai.message.requireLength
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.network.protocol.tim.packet.event.EventPacket
import net.mamoe.mirai.network.qqAccount
import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.configureBody
import net.mamoe.mirai.utils.httpClient
import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.withSession
import kotlin.coroutines.coroutineContext
@ -125,13 +132,18 @@ internal suspend inline fun HttpClient.postImage(
imageInput.close()
}
internal suspend inline fun HttpClient.download(
url: String
): ByteArray = get<HttpResponse>(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<FriendImageIdDownloadLinkRequestPacket.DownloadLink>() {
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<FriendImageIdRequestPacket.Response>() {
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<FriendImageIdRequestPac
@Suppress("ControlFlowWithEmptyBody")
while (readUByte().toUInt() != 0x4Au);
val uKey = readBytes(readUnsignedVarInt().toInt())//128
val uKey = readBytes(readUVarInt().toInt())//128
discardExact(1)//52, id
val imageId = ImageId(readString(readUnsignedVarInt().toInt()))//37
val imageId = ImageId(readString(readUVarInt().toInt()))//37
return Response.RequireUpload(uKey, imageId)
} else {
val toDiscard = readUByte().toInt() - 37
@ -331,7 +417,7 @@ object FriendImageIdRequestPacket : SessionPacketFactory<FriendImageIdRequestPac
* 获取 Image Id 和上传用的一个 uKey
*/
@AnnotatedId(KnownPacketId.GROUP_IMAGE_ID)
@PacketVersion(date = "2019.10.26", timVersion = "2.3.2.21173")
@PacketVersion(date = "2019.10.26", timVersion = "2.3.2 (21173)")
object GroupImageIdRequestPacket : SessionPacketFactory<GroupImageIdRequestPacket.Response>() {
operator fun invoke(
bot: UInt,
@ -343,13 +429,13 @@ object GroupImageIdRequestPacket : SessionPacketFactory<GroupImageIdRequestPacke
writeHex("04 00 00 00 01 01 01 00 00 68 20 00 00 00 00 00 00 00 00")
encryptAndWrite(sessionKey) {
writeHex("00 00 00 07 00 00 00")
writeHex("00 00 00 07 00 00")
writeUVarintLVPacket(lengthOffset = { it - 7 }) {
writeShortLVPacket(lengthOffset = { it - 7 }) {
writeByte(0x08)
writeHex("01 12 03 98 01 01 10 01 1A")
writeUVarintLVPacket(lengthOffset = { it }) {
writeUVarIntLVPacket(lengthOffset = { it }) {
writeTUVarint(0x08u, groupInternalId.value)
writeTUVarint(0x10u, bot)
writeTV(0x1800u)
@ -359,7 +445,7 @@ object GroupImageIdRequestPacket : SessionPacketFactory<GroupImageIdRequestPacke
writeFully(image.md5)
writeTUVarint(0x28u, image.inputSize.toUInt())
writeUVarintLVPacket(tag = 0x32u) {
writeUVarIntLVPacket(tag = 0x32u) {
writeTV(0x5B_00u)
writeTV(0x40_00u)
writeTV(0x33_00u)