Commit a2f35f5d authored by Him188's avatar Him188

ExternalImage

parent 0d7cc17c
......@@ -7,7 +7,9 @@ import net.mamoe.mirai.message.Message
import net.mamoe.mirai.message.MessageChain
import net.mamoe.mirai.message.PlainText
import net.mamoe.mirai.message.toChain
import net.mamoe.mirai.network.BotSession
import net.mamoe.mirai.network.protocol.tim.handler.EventPacketHandler
import net.mamoe.mirai.withSession
class ContactList<C : Contact> : MutableMap<UInt, C> by mutableMapOf()
......@@ -79,6 +81,8 @@ class Group internal constructor(bot: Bot, id: UInt) : Contact(bot, id) {
companion object
}
inline fun <R> Group.withSession(block: BotSession.() -> R): R = bot.withSession(block)
/**
* QQ 账号.
* 注意: 一个 [QQ] 实例并不是独立的, 它属于一个 [Bot].
......
......@@ -6,19 +6,17 @@ import kotlinx.io.core.IoBuffer
import kotlinx.io.core.buildPacket
import kotlinx.io.streams.asInput
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.io.OutputStream
import java.security.MessageDigest
import javax.imageio.ImageIO
import java.awt.image.BufferedImage as JavaBufferedImage
fun JavaBufferedImage.toMiraiImage(formatName: String = "gif"): ExternalImage {
fun JavaBufferedImage.toExternalImage(formatName: String = "gif"): ExternalImage {
val digest = MessageDigest.getInstance("md5")
digest.reset()
val buffer = buildPacket {
ImageIO.write(this@toMiraiImage, formatName, object : OutputStream() {
ImageIO.write(this@toExternalImage, formatName, object : OutputStream() {
override fun write(b: Int) {
b.toByte().let {
this@buildPacket.writeByte(it)
......@@ -31,33 +29,16 @@ fun JavaBufferedImage.toMiraiImage(formatName: String = "gif"): ExternalImage {
return ExternalImage(width, height, digest.digest(), formatName, buffer)
}
fun ExternalImage.toJavaImage(): JavaBufferedImage = ImageIO.read(object : InputStream() {
override fun read(): Int = with(this@toJavaImage.input) {
if (!endOfInput)
readByte().toInt()
else -1
}
})
fun File.toMiraiImage(): ExternalImage {
val image = ImageIO.getImageReaders(this.inputStream()).asSequence().first()
val digest = MessageDigest.getInstance("md5")
digest.reset()
FileInputStream(this).transferTo(object : OutputStream() {
override fun write(b: Int) {
b.toByte().let {
digest.update(it)
}
}
})
fun File.toExternalImage(): ExternalImage {
val input = ImageIO.createImageInputStream(this)
val image = ImageIO.getImageReaders(input).asSequence().firstOrNull() ?: error("Unable to read file(${this.path}), no ImageReader found")
image.input = input
val dimension = image.defaultReadParam.sourceRenderSize
return ExternalImage(
width = dimension.width,
height = dimension.height,
md5 = digest.digest(),
format = image.formatName,
width = image.getWidth(0),
height = image.getHeight(0),
md5 = this.md5(),
imageFormat = image.formatName,
input = this.inputStream().asInput(IoBuffer.Pool),
inputSize = this.length()
)
......
......@@ -7,16 +7,11 @@ import io.ktor.client.engine.cio.CIO
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.http.ContentType
import io.ktor.http.content.OutgoingContent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.io.ByteWriteChannel
import kotlinx.coroutines.io.writeFully
import kotlinx.coroutines.withContext
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.Input
import kotlinx.io.core.readBytes
import kotlinx.io.core.readFully
import org.jsoup.Connection
import org.jsoup.Jsoup
import java.io.File
import java.io.OutputStream
import java.net.InetAddress
import java.security.MessageDigest
import java.util.zip.CRC32
......@@ -31,56 +26,75 @@ actual fun crc32(key: ByteArray): Int = CRC32().let { it.update(key); it.value.t
actual fun md5(byteArray: ByteArray): ByteArray = MessageDigest.getInstance("MD5").digest(byteArray)
fun File.md5(): ByteArray {
val digest = MessageDigest.getInstance("md5")
digest.reset()
this.inputStream().transferTo(object : OutputStream() {
override fun write(b: Int) {
b.toByte().let {
digest.update(it)
}
}
})
return digest.digest()
}
actual fun solveIpAddress(hostname: String): String = InetAddress.getByName(hostname).hostAddress
actual fun localIpAddress(): String = InetAddress.getLocalHost().hostAddress
suspend fun httpPostFriendImageOld(
uKeyHex: String,
botNumber: UInt,
imageData: ByteReadPacket
): Boolean = Jsoup.connect("http://htdata2.qq.com/cgi-bin/httpconn" +
"?htcmd=0x6ff0070" +
"&ver=5603" +
"&ukey=${uKeyHex}" +
"&filezise=${imageData.remaining}" +
"&range=0" +
"&uin=$botNumber"
/*
actual suspend fun httpPostFriendImageOld(
uKeyHex: String,
botNumber: UInt,
imageData: ByteReadPacket
): Boolean = Jsoup.connect(
"http://htdata2.qq.com/cgi-bin/httpconn" +
"?htcmd=0x6ff0070" +
"&ver=5603" +
"&ukey=$uKeyHex" +
"&filezise=${imageData.remaining}" +
"&range=0" +
"&uin=$botNumber"
)
.postImage(imageData)
.postImage(imageData)
private suspend fun Connection.postImage(image: ByteReadPacket): Boolean = this
.userAgent("QQClient")
.header("Content-Length", image.remaining.toString())
.requestBody(String(image.readBytes(), Charsets.ISO_8859_1))
.method(Connection.Method.POST)
.postDataCharset("ISO_8859_1")
.header("Content-type", "image/gif")
.ignoreContentType(true)
.suspendExecute()
.statusCode() == 200
.userAgent("QQClient")
.header("Content-Length", image.remaining.toString())
.requestBody(String(image.readBytes(), Charsets.ISO_8859_1))
.method(Connection.Method.POST)
.postDataCharset("ISO_8859_1")
.header("Content-type", "image/gif")
.ignoreContentType(true)
.suspendExecute()
.statusCode() == 200
private suspend fun Connection.suspendExecute(): Connection.Response = withContext(Dispatchers.IO) {
execute()
}
*/
internal actual val httpClient: HttpClient = HttpClient(CIO)
internal actual fun HttpRequestBuilder.configureBody(
inputSize: Long,
input: Input
inputSize: Long,
input: Input
) {
body = object : OutgoingContent.WriteChannelContent() {
override val contentType: ContentType = ContentType.Image.GIF
override val contentLength: Long = inputSize
override suspend fun writeTo(channel: ByteWriteChannel) {//不知道为什么这个 channel 在 common 找不到...
val buffer = byteArrayOf(1)
while (!input.endOfInput) {
input.readFully(buffer)
channel.writeFully(buffer)
}
}
//body = ByteArrayContent(input.readBytes(), ContentType.Image.PNG)
body = object : OutgoingContent.WriteChannelContent() {
override val contentType: ContentType = ContentType.Image.PNG
override val contentLength: Long = inputSize
override suspend fun writeTo(channel: ByteWriteChannel) {//不知道为什么这个 channel 在 common 找不到...
val buffer = byteArrayOf(1)
repeat(contentLength.toInt()) {
input.readFully(buffer)
channel.writeFully(buffer, 0, buffer.size)
}
}
}
}
\ No newline at end of file
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