Commit 867c0d62 authored by Him188's avatar Him188

Downloading image is now available

parent 8b3d710e
...@@ -30,7 +30,7 @@ class ActionPacketHandler(session: BotSession) : PacketHandler(session) { ...@@ -30,7 +30,7 @@ class ActionPacketHandler(session: BotSession) : PacketHandler(session) {
override suspend fun onPacketReceived(packet: Packet): Unit = with(session) { override suspend fun onPacketReceived(packet: Packet): Unit = with(session) {
when (packet) { when (packet) {
is SKey -> { is SKey -> {
_sKey = packet.delegate _sKey = packet.value
cookies = "uin=o$qqAccount;skey=$sKey;" cookies = "uin=o$qqAccount;skey=$sKey;"
......
package net.mamoe.mirai.network.protocol.tim.packet.action
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.contact.withSession
import net.mamoe.mirai.message.Image
import net.mamoe.mirai.message.ImageLink
import net.mamoe.mirai.network.protocol.tim.packet.action.FriendImageIdDownloadLinkRequestPacket.ImageLinkResponse
import net.mamoe.mirai.network.sessionKey
import net.mamoe.mirai.qqAccount
suspend fun QQ.getLink(image: Image): ImageLink = withSession {
FriendImageIdDownloadLinkRequestPacket(bot.qqAccount, bot.sessionKey, id, image.id).sendAndExpect<ImageLinkResponse>().link
}
suspend inline fun QQ.downloadAsByteArray(image: Image): ByteArray = this.getLink(image).downloadAsByteArray()
\ No newline at end of file
...@@ -35,6 +35,7 @@ fun Input.readUShortLVByteArray(): ByteArray = this.readBytes(this.readUShort(). ...@@ -35,6 +35,7 @@ fun Input.readUShortLVByteArray(): ByteArray = this.readBytes(this.readUShort().
private inline fun <R> inline(block: () -> R): R = block() private inline fun <R> inline(block: () -> R): R = block()
@Suppress("DuplicatedCode")
fun Input.readTLVMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMap<UInt, ByteArray> { fun Input.readTLVMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMap<UInt, ByteArray> {
val map = mutableMapOf<UInt, ByteArray>() val map = mutableMapOf<UInt, ByteArray>()
var type: UShort = 0u var type: UShort = 0u
...@@ -66,6 +67,42 @@ fun Input.readTLVMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMa ...@@ -66,6 +67,42 @@ fun Input.readTLVMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMa
return map return map
} }
/**
* 读扁平的 tag-UVarInt map. 重复的 tag 将不会只保留最后一个
*
* tag: UByte
* value: UVarint
*/
@Suppress("DuplicatedCode")
fun Input.readFlatTUVarIntMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMap<UInt, UInt> {
val map = mutableMapOf<UInt, UInt>()
var type: UShort = 0u
while (inline {
try {
type = when (tagSize) {
1 -> readUByte().toUShort()
2 -> readUShort()
else -> error("Unsupported tag size: $tagSize")
}
} catch (e: EOFException) {
if (expectingEOF) {
return map
}
throw e
}
type
}.toUByte() != UByte.MAX_VALUE) {
if (map.containsKey(type.toUInt())) {
map[type.toUInt()] = this.readUVarInt()
} else {
map[type.toUInt()] = this.readUVarInt()
}
}
return map
}
fun Map<UInt, ByteArray>.printTLVMap(name: String) = fun Map<UInt, ByteArray>.printTLVMap(name: String) =
debugPrintln("TLVMap $name= " + this.mapValues { (_, value) -> value.toUHexString() }.mapKeys { it.key.toInt().toUShort().toUHexString() }) debugPrintln("TLVMap $name= " + this.mapValues { (_, value) -> value.toUHexString() }.mapKeys { it.key.toInt().toUShort().toUHexString() })
......
...@@ -120,7 +120,7 @@ object PacketDebugger { ...@@ -120,7 +120,7 @@ object PacketDebugger {
* 7. 运行完 `mov eax,dword ptr ss:[ebp+10]` * 7. 运行完 `mov eax,dword ptr ss:[ebp+10]`
* 8. 查看内存, `eax` 到 `eax+10` 的 16 字节就是 `sessionKey` * 8. 查看内存, `eax` 到 `eax+10` 的 16 字节就是 `sessionKey`
*/ */
val sessionKey: SessionKey = SessionKey("52 A2 10 EC C7 A8 80 44 FF 65 6C 70 43 A6 E7 73".hexToBytes()) val sessionKey: SessionKey = SessionKey("4D 60 96 90 90 67 02 A2 4E 1C 78 32 2E 30 2C 99".hexToBytes())
const val qq: UInt = 1040400290u const val qq: UInt = 1040400290u
val IgnoredPacketIdList: List<PacketId> = listOf( val IgnoredPacketIdList: List<PacketId> = listOf(
......
...@@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON ...@@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON
import kotlinx.coroutines.* import kotlinx.coroutines.*
import net.mamoe.mirai.contact.Contact import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.message.Image import net.mamoe.mirai.message.Image
import net.mamoe.mirai.message.upload import net.mamoe.mirai.message.uploadAsImage
import org.jsoup.Jsoup import org.jsoup.Jsoup
class GentleImage { class GentleImage {
...@@ -58,7 +58,7 @@ class GentleImage { ...@@ -58,7 +58,7 @@ class GentleImage {
.execute() .execute()
.bodyStream() .bodyStream()
} }
}?.upload(contact) ?: error("Unable to download image") }?.uploadAsImage(contact) ?: error("Unable to download image")
} }
} }
......
...@@ -12,11 +12,15 @@ import net.mamoe.mirai.event.Subscribable ...@@ -12,11 +12,15 @@ import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.event.subscribeAlways import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeMessages import net.mamoe.mirai.event.subscribeMessages
import net.mamoe.mirai.message.Image import net.mamoe.mirai.message.Image
import net.mamoe.mirai.message.sendAsImageTo
import net.mamoe.mirai.network.protocol.tim.packet.action.download
import net.mamoe.mirai.network.protocol.tim.packet.action.downloadAsByteArray import net.mamoe.mirai.network.protocol.tim.packet.action.downloadAsByteArray
import net.mamoe.mirai.network.protocol.tim.packet.action.downloadTo
import net.mamoe.mirai.network.protocol.tim.packet.event.FriendMessage import net.mamoe.mirai.network.protocol.tim.packet.event.FriendMessage
import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess
import net.mamoe.mirai.utils.currentTime import net.mamoe.mirai.utils.currentTime
import java.io.File import java.io.File
import javax.swing.filechooser.FileSystemView
import kotlin.random.Random import kotlin.random.Random
private fun readTestAccount(): BotAccount? { private fun readTestAccount(): BotAccount? {
...@@ -65,13 +69,24 @@ suspend fun main() { ...@@ -65,13 +69,24 @@ suspend fun main() {
if (this is FriendMessage) { if (this is FriendMessage) {
withContext(IO) { withContext(IO) {
reply(message[Image] + " downloading") reply(message[Image] + " downloading")
sender.downloadAsByteArray(message[Image]).inputStream()
.transferTo(File(System.getProperty("user.dir", "testDownloadedImage${currentTime}.png")).outputStream()) sender.downloadTo(message[Image], File(System.getProperty("user.dir"), "testDownloadedImage${currentTime}.png").also { it.createNewFile() })
reply(message[Image] + " downloaded") reply(message[Image].id.value + " downloaded")
} }
} }
} }
startsWith("上传图片", removePrefix = true) handler@{
val file = File(FileSystemView.getFileSystemView().homeDirectory, it)
if (!file.exists()) {
reply("图片不存在")
return@handler
}
reply("sent")
file.sendAsImageTo(subject)
}
startsWith("随机图片", removePrefix = true) { startsWith("随机图片", removePrefix = true) {
repeat(it.toIntOrNull() ?: 1) { repeat(it.toIntOrNull() ?: 1) {
GlobalScope.launch { GlobalScope.launch {
......
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