mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-09 18:00:33 +08:00
Rename responses
This commit is contained in:
parent
e3add09391
commit
1c9994e87d
@ -20,8 +20,8 @@ import net.mamoe.mirai.network.protocol.tim.handler.TemporaryPacketHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.Packet
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.SessionKey
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.action.FriendImageLink
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.action.FriendImagePacket
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.action.ImageLink
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.getGTK
|
||||
import net.mamoe.mirai.utils.internal.PositiveNumbers
|
||||
@ -142,7 +142,7 @@ abstract class BotSessionBase(
|
||||
suspend inline fun GroupId.group(): Group = bot.getGroup(this)
|
||||
suspend inline fun GroupInternalId.group(): Group = bot.getGroup(this)
|
||||
|
||||
suspend fun Image.getLink(): ImageLink = FriendImagePacket.RequestImageLink(bot.qqAccount, bot.sessionKey, id).sendAndExpect()
|
||||
suspend fun Image.getLink(): FriendImageLink = FriendImagePacket.RequestImageLink(bot.qqAccount, bot.sessionKey, id).sendAndExpect()
|
||||
suspend inline fun Image.downloadAsByteArray(): ByteArray = getLink().downloadAsByteArray()
|
||||
suspend inline fun Image.download(): ByteReadPacket = getLink().download()
|
||||
}
|
||||
|
@ -2,9 +2,6 @@
|
||||
|
||||
package net.mamoe.mirai.network.protocol.tim.packet
|
||||
|
||||
import net.mamoe.mirai.event.Subscribable
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
/**
|
||||
* 包 ID. 除特殊外, [PacketFactory] 都需要这个注解来指定包 ID.
|
||||
@ -18,18 +15,6 @@ annotation class AnnotatedId( // 注解无法在 JS 平台使用, 但现在暂
|
||||
|
||||
inline val AnnotatedId.value: UShort get() = id.value
|
||||
|
||||
|
||||
/**
|
||||
* 标记这个包对应的事件.
|
||||
* 这个注解应该被标记在 [Packet] 上
|
||||
*/
|
||||
@MustBeDocumented
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class CorrespondingEvent(
|
||||
val eventClass: KClass<out Subscribable>
|
||||
)
|
||||
|
||||
/**
|
||||
* 包的最后一次修改时间, 和分析时使用的 TIM 版本
|
||||
*/
|
||||
|
@ -74,7 +74,7 @@ enum class KnownPacketId(override inline val value: UShort, override inline val
|
||||
inline CAN_ADD_FRIEND(0x00A7u, CanAddFriendPacket),
|
||||
inline ADD_FRIEND(0x00A8u, AddFriendPacket),
|
||||
inline REQUEST_FRIEND_ADDITION_KEY(0x00AEu, RequestFriendAdditionKeyPacket),
|
||||
inline GROUP_IMAGE_ID(0x0388u, GroupImageIdRequestPacket),
|
||||
inline GROUP_IMAGE_ID(0x0388u, GroupImagePacket),
|
||||
inline FRIEND_IMAGE_ID(0x0352u, FriendImagePacket),
|
||||
|
||||
inline REQUEST_PROFILE_AVATAR(0x0031u, RequestProfileAvatarPacket),
|
||||
|
@ -22,6 +22,7 @@ import net.mamoe.mirai.network.qqAccount
|
||||
import net.mamoe.mirai.qqAccount
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.Http
|
||||
import net.mamoe.mirai.utils.assertUnreachable
|
||||
import net.mamoe.mirai.utils.configureBody
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
import net.mamoe.mirai.withSession
|
||||
@ -42,11 +43,11 @@ class OverFileSizeMaxException : IllegalStateException()
|
||||
*/
|
||||
suspend fun Group.uploadImage(image: ExternalImage): ImageId = withSession {
|
||||
val userContext = coroutineContext
|
||||
val response = GroupImageIdRequestPacket(bot.qqAccount, internalId, image, sessionKey).sendAndExpect<GroupImageIdRequestPacket.Response>()
|
||||
val response = GroupImagePacket.RequestImageId(bot.qqAccount, internalId, image, sessionKey).sendAndExpect<GroupImageResponse>()
|
||||
|
||||
withContext(userContext) {
|
||||
when (response) {
|
||||
is GroupImageIdRequestPacket.Response.RequireUpload -> Http.postImage(
|
||||
is GroupImageUKey -> Http.postImage(
|
||||
htcmd = "0x6ff0071",
|
||||
uin = bot.qqAccount,
|
||||
groupId = GroupId(id),
|
||||
@ -55,10 +56,11 @@ suspend fun Group.uploadImage(image: ExternalImage): ImageId = withSession {
|
||||
uKeyHex = response.uKey.toUHexString("")
|
||||
)
|
||||
|
||||
is GroupImageIdRequestPacket.Response.AlreadyExists -> {
|
||||
is GroupImageAlreadyExists -> {
|
||||
}
|
||||
|
||||
is GroupImageIdRequestPacket.Response.OverFileSizeMax -> throw OverFileSizeMaxException()
|
||||
is GroupImageOverFileSizeMax -> throw OverFileSizeMaxException()
|
||||
else -> assertUnreachable()
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,9 +77,9 @@ suspend fun Group.uploadImage(image: ExternalImage): ImageId = withSession {
|
||||
*/
|
||||
suspend fun QQ.uploadImage(image: ExternalImage): ImageId = bot.withSession {
|
||||
FriendImagePacket.RequestImageId(qqAccount, sessionKey, id, image)
|
||||
.sendAndExpectAsync<ImageResponse, ImageId> {
|
||||
.sendAndExpectAsync<FriendImageResponse, ImageId> {
|
||||
return@sendAndExpectAsync when (it) {
|
||||
is ImageUKey -> {
|
||||
is FriendImageUKey -> {
|
||||
Http.postImage(
|
||||
htcmd = "0x6ff0070",
|
||||
uin = bot.qqAccount,
|
||||
@ -88,8 +90,8 @@ suspend fun QQ.uploadImage(image: ExternalImage): ImageId = bot.withSession {
|
||||
)
|
||||
it.imageId
|
||||
}
|
||||
is ImageAlreadyExists -> it.imageId
|
||||
is ImageOverFileSizeMax -> throw OverFileSizeMaxException()
|
||||
is FriendImageAlreadyExists -> it.imageId
|
||||
is FriendImageOverFileSizeMax -> throw OverFileSizeMaxException()
|
||||
else -> error("This shouldn't happen")
|
||||
}
|
||||
}.await()
|
||||
@ -183,41 +185,83 @@ object SubmitImageFilenamePacket : PacketFactory {
|
||||
}
|
||||
}*/
|
||||
|
||||
interface ImageResponse : EventPacket
|
||||
// region FriendImageResponse
|
||||
|
||||
interface FriendImageResponse : EventPacket
|
||||
|
||||
/**
|
||||
* 图片数据地址.
|
||||
*/
|
||||
// TODO: 2019/11/15 应该为 inline class, 但 kotlin 有 bug
|
||||
data class ImageLink(inline val value: String) : ImageResponse {
|
||||
data class FriendImageLink(inline val value: String) : FriendImageResponse {
|
||||
suspend fun downloadAsByteArray(): ByteArray = download().readBytes()
|
||||
suspend fun download(): ByteReadPacket = Http.get(value)
|
||||
|
||||
override fun toString(): String = "ImageLink($value)"
|
||||
override fun toString(): String = "FriendImageLink($value)"
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问 HTTP API 时使用的 uKey
|
||||
*/
|
||||
class ImageUKey(inline val imageId: ImageId, inline val uKey: ByteArray) : ImageResponse {
|
||||
override fun toString(): String = "ImageUKey(imageId=${imageId.value}, uKey=${uKey.toUHexString()})"
|
||||
class FriendImageUKey(inline val imageId: ImageId, inline val uKey: ByteArray) : FriendImageResponse {
|
||||
override fun toString(): String = "FriendImageUKey(imageId=${imageId.value}, uKey=${uKey.toUHexString()})"
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片 ID 已存在
|
||||
* 发送消息时使用的 id
|
||||
*/
|
||||
inline class ImageAlreadyExists(inline val imageId: ImageId) : ImageResponse {
|
||||
inline class FriendImageAlreadyExists(inline val imageId: ImageId) : FriendImageResponse {
|
||||
override fun toString(): String = "FriendImageAlreadyExists(imageId=${imageId.value})"
|
||||
}
|
||||
|
||||
/**
|
||||
* 超过文件大小上限
|
||||
*/
|
||||
object ImageOverFileSizeMax : ImageResponse {
|
||||
object FriendImageOverFileSizeMax : FriendImageResponse {
|
||||
override fun toString(): String = "FriendImageOverFileSizeMax"
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// regiion GroupImageResponse
|
||||
interface GroupImageResponse : EventPacket
|
||||
|
||||
/**
|
||||
* 图片数据地址.
|
||||
*/
|
||||
// TODO: 2019/11/15 应该为 inline class, 但 kotlin 有 bug
|
||||
data class GroupImageLink(inline val value: String) : GroupImageResponse {
|
||||
suspend fun downloadAsByteArray(): ByteArray = download().readBytes()
|
||||
suspend fun download(): ByteReadPacket = Http.get(value)
|
||||
|
||||
override fun toString(): String = "GroupImageLink($value)"
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问 HTTP API 时使用的 uKey
|
||||
*/
|
||||
inline class GroupImageUKey(inline val uKey: ByteArray) : GroupImageResponse {
|
||||
override fun toString(): String = "GroupImageUKey(uKey=${uKey.toUHexString()})"
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片 ID 已存在
|
||||
* 发送消息时使用的 id
|
||||
*/
|
||||
object GroupImageAlreadyExists : GroupImageResponse {
|
||||
override fun toString(): String = "GroupImageAlreadyExists"
|
||||
}
|
||||
|
||||
/**
|
||||
* 超过文件大小上限
|
||||
*/
|
||||
object GroupImageOverFileSizeMax : GroupImageResponse {
|
||||
override fun toString(): String = "GroupImageOverFileSizeMax"
|
||||
|
||||
}
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* 请求上传图片. 将发送图片的 md5, size, width, height.
|
||||
* 服务器返回以下之一:
|
||||
@ -226,7 +270,7 @@ object ImageOverFileSizeMax : ImageResponse {
|
||||
*/
|
||||
@AnnotatedId(KnownPacketId.FRIEND_IMAGE_ID)
|
||||
@PacketVersion(date = "2019.11.16", timVersion = "2.3.2 (21173)")
|
||||
object FriendImagePacket : SessionPacketFactory<ImageResponse>() {
|
||||
object FriendImagePacket : SessionPacketFactory<FriendImageResponse>() {
|
||||
@Suppress("FunctionName")
|
||||
fun RequestImageId(
|
||||
bot: UInt,
|
||||
@ -333,8 +377,7 @@ object FriendImagePacket : SessionPacketFactory<ImageResponse>() {
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): ImageResponse =
|
||||
with(this) {
|
||||
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): FriendImageResponse {
|
||||
|
||||
// 上传图片, 成功获取ID
|
||||
//00 00 00 08 00 00
|
||||
@ -364,7 +407,7 @@ object FriendImagePacket : SessionPacketFactory<ImageResponse>() {
|
||||
//00 00 00 09 00 00 00 1D 12 07 98 01 01 A0 01 C7 01 08 01 12 19 08 00 18 C7 01 22 12 66 69 6C 65 20 73 69 7A 65 20 6F 76 65 72 20 6D 61 78
|
||||
discardExact(3) // 00 00 00
|
||||
if (readUByte().toUInt() == 0x09u) {
|
||||
return ImageOverFileSizeMax
|
||||
return FriendImageOverFileSizeMax
|
||||
}
|
||||
discardExact(2) //00 00
|
||||
|
||||
@ -373,23 +416,23 @@ object FriendImagePacket : SessionPacketFactory<ImageResponse>() {
|
||||
discardExact(1); discardExact(readUVarInt().toInt()) // 12 06 98 01 01 A0 01 00
|
||||
|
||||
check(readUByte().toUInt() == 0x08u)
|
||||
when (val flag = readUByte().toUInt()) {
|
||||
return when (val flag = readUByte().toUInt()) {
|
||||
0x01u -> {
|
||||
try {
|
||||
while (readUByte().toUInt() != 0x4Au) readUVarLong()
|
||||
val uKey = readBytes(readUVarInt().toInt())//128
|
||||
while (readUByte().toUInt() != 0x52u) readUVarLong()
|
||||
val imageId = ImageId(readString(readUVarInt().toInt()))//37
|
||||
return ImageUKey(imageId, uKey)
|
||||
return FriendImageUKey(imageId, uKey)
|
||||
} catch (e: EOFException) {
|
||||
val toDiscard = readUByte().toInt() - 37
|
||||
|
||||
return if (toDiscard < 0) {
|
||||
ImageOverFileSizeMax
|
||||
FriendImageOverFileSizeMax
|
||||
} else {
|
||||
discardExact(toDiscard)
|
||||
val imageId = ImageId(readString(37))
|
||||
ImageAlreadyExists(imageId)
|
||||
FriendImageAlreadyExists(imageId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -425,7 +468,7 @@ object FriendImagePacket : SessionPacketFactory<ImageResponse>() {
|
||||
|
||||
val link = readUVarIntLVString()
|
||||
discard()
|
||||
ImageLink(link)
|
||||
FriendImageLink(link)
|
||||
}
|
||||
else -> error("Unknown FriendImageIdRequestPacket flag $flag")
|
||||
}
|
||||
@ -438,22 +481,20 @@ object FriendImagePacket : SessionPacketFactory<ImageResponse>() {
|
||||
*/
|
||||
@AnnotatedId(KnownPacketId.GROUP_IMAGE_ID)
|
||||
@PacketVersion(date = "2019.10.26", timVersion = "2.3.2 (21173)")
|
||||
object GroupImageIdRequestPacket : SessionPacketFactory<GroupImageIdRequestPacket.Response>() {
|
||||
operator fun invoke(
|
||||
object GroupImagePacket : SessionPacketFactory<GroupImageResponse>() {
|
||||
@Suppress("FunctionName")
|
||||
fun RequestImageId(
|
||||
bot: UInt,
|
||||
groupInternalId: GroupInternalId,
|
||||
image: ExternalImage,
|
||||
sessionKey: SessionKey
|
||||
): OutgoingPacket = buildOutgoingPacket {
|
||||
writeQQ(bot)
|
||||
writeHex("04 00 00 00 01 01 01 00 00 68 20 00 00 00 00 00 00 00 00")
|
||||
|
||||
encryptAndWrite(sessionKey) {
|
||||
): OutgoingPacket = buildSessionPacket(bot, sessionKey, version = TIMProtocol.version0x04) {
|
||||
writeHex("00 00 00 07 00 00")
|
||||
|
||||
writeShortLVPacket(lengthOffset = { it - 7 }) {
|
||||
writeByte(0x08)
|
||||
writeHex("01 12 03 98 01 01 10 01 1A")
|
||||
// 02 10 02 22
|
||||
|
||||
writeUVarIntLVPacket(lengthOffset = { it }) {
|
||||
writeTUVarint(0x08u, groupInternalId.value)
|
||||
@ -493,49 +534,85 @@ object GroupImageIdRequestPacket : SessionPacketFactory<GroupImageIdRequestPacke
|
||||
writeUByte(0u)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RequestImageLink(
|
||||
bot: UInt,
|
||||
sessionKey: SessionKey,
|
||||
imageId: ImageId
|
||||
): OutgoingPacket {
|
||||
imageId.requireLength()
|
||||
require(imageId.value.length == 37) { "ImageId.value.length must == 37" }
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
// 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]
|
||||
// 10 [A6 A7 F1 EA 02]
|
||||
// 1A [25] 2F 39 61 31 66 37 31 36 32 2D 38 37 30 38 2D 34 39 30 38 2D 38 31 63 30 2D 66 34 63 64 66 33 35 63 38 64 37 65
|
||||
// 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")
|
||||
|
||||
writeUShort(0x004Bu)
|
||||
|
||||
writeUByte(0x08u)
|
||||
writeTV(0x01_12u)
|
||||
writeTV(0x03_98u)
|
||||
writeTV(0x01_02u)
|
||||
writeTV(0x08_02u)
|
||||
|
||||
writeUByte(0x1Au)
|
||||
writeUByte(0x47u)
|
||||
writeTUVarint(0x08u, bot)
|
||||
writeTUVarint(0x10u, bot)
|
||||
writeTLV(0x1Au, imageId.value.toByteArray(Charsets.ISO_8859_1))
|
||||
writeHex("20 02 30 04 38 20 40 FF 01 50 00 6A 05 32 36 39 33 33 78 01")
|
||||
}
|
||||
}
|
||||
|
||||
private val value0x6A: UByteArray = ubyteArrayOf(0x05u, 0x32u, 0x36u, 0x36u, 0x35u, 0x36u)
|
||||
|
||||
sealed class Response : EventPacket {
|
||||
data class RequireUpload(
|
||||
/**
|
||||
* 访问 HTTP API 时需要使用的一个 key. 128 位
|
||||
*/
|
||||
val uKey: ByteArray
|
||||
) : Response() {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is RequireUpload) return false
|
||||
if (!uKey.contentEquals(other.uKey)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = uKey.contentHashCode()
|
||||
}
|
||||
|
||||
object AlreadyExists : Response() {
|
||||
override fun toString(): String = this::class.simpleName!!
|
||||
}
|
||||
|
||||
/**
|
||||
* 超过文件大小上限
|
||||
*/
|
||||
object OverFileSizeMax : Response() {
|
||||
override fun toString(): String = this::class.simpleName!!
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): Response {
|
||||
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): GroupImageResponse {
|
||||
discardExact(6)//00 00 00 05 00 00
|
||||
|
||||
val length = remaining - 128 - 14
|
||||
if (length < 0) {
|
||||
return if (readUShort().toUInt() == 0x0025u) Response.OverFileSizeMax else Response.AlreadyExists
|
||||
return if (readUShort().toUInt() == 0x0025u) GroupImageOverFileSizeMax else GroupImageAlreadyExists
|
||||
}
|
||||
|
||||
discardExact(length)
|
||||
return Response.RequireUpload(readBytes(128))
|
||||
return GroupImageUKey(readBytes(128))
|
||||
}
|
||||
|
||||
// 下载图片
|
||||
// 00 00 00 05 00 00
|
||||
// [02 46]
|
||||
// 12 03 98 01 02 08 9B A4 D4 9A 0A 10 02 22 BB 04 08 92 A8 B2 D3 0A 12 10 EB 1A 34 01 8F 1E B4 73 39 34 F0 65 68 80 A7 52 18 00 48 BD EE 92 CD 01 48 BD EE 92 E5 01 48 B4 C3 A9 E8 06 48 BA F6 D7 5C 48 EF BC A4 DC 07 50 50 50 50 50 50 50 50 50 50 5A 0D 67 63 68 61 74 2E 71 70 69 63 2E 63 6E 62 77 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 38 31 34 37 37 37 32 33 30 2F 38 31 34 37 37 37 32 33 30 2D 32 38 35 39 32 34 32 35 31 34 2D 45 42 31 41 33 34 30 31 38 46 31 45 42 34 37 33 33 39 33 34 46 30 36 35 36 38 38 30 41 37 35 32 2F 31 39 38 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 6A 75 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 38 31 34 37 37 37 32 33 30 2F 38 31 34 37 37 37 32 33 30 2D 32 38 35 39 32 34 32 35 31 34 2D 45 42 31 41 33 34 30 31 38 46 31 45 42 34 37 33 33 39 33 34 46 30 36 35 36 38 38 30 41 37 35 32 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 72 77 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 38 31 34 37 37 37 32 33 30 2F 38 31 34 37 37 37 32 33 30 2D 32 38 35 39 32 34 32 35 31 34 2D 45 42 31 41 33 34 30 31 38 46 31 45 42 34 37 33 33 39 33 34 46 30 36 35 36 38 38 30 41 37 35 32 2F 37 32 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 78 00 80 01 03 9A 01 77 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 38 31 34 37 37 37 32 33 30 2F 38 31 34 37 37 37 32 33 30 2D 32 38 35 39 32 34 32 35 31 34 2D 45 42 31 41 33 34 30 31 38 46 31 45 42 34 37 33 33 39 33 34 46 30 36 35 36 38 38 30 41 37 35 32 2F 34 30 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 A0 01 00
|
||||
}
|
@ -15,8 +15,8 @@ import net.mamoe.mirai.event.events.BotEvent
|
||||
import net.mamoe.mirai.message.*
|
||||
import net.mamoe.mirai.message.internal.readMessageChain
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.PacketVersion
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.action.FriendImageLink
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.action.FriendImagePacket
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.action.ImageLink
|
||||
import net.mamoe.mirai.network.sessionKey
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.io.printTLVMap
|
||||
@ -88,7 +88,7 @@ abstract class MessagePacketBase<TSubject : Contact> : EventPacket, BotEvent() {
|
||||
|
||||
// region Image download
|
||||
|
||||
suspend fun Image.getLink(): ImageLink = bot.withSession { FriendImagePacket.RequestImageLink(bot.qqAccount, bot.sessionKey, id).sendAndExpect() }
|
||||
suspend fun Image.getLink(): FriendImageLink = bot.withSession { FriendImagePacket.RequestImageLink(bot.qqAccount, bot.sessionKey, id).sendAndExpect() }
|
||||
suspend inline fun Image.downloadAsByteArray(): ByteArray = getLink().downloadAsByteArray()
|
||||
suspend inline fun Image.download(): ByteReadPacket = getLink().download()
|
||||
// endregion
|
||||
|
Loading…
Reference in New Issue
Block a user