Commit 046d8968 authored by Him188's avatar Him188

Cleanup

parent 0717ff77
...@@ -25,7 +25,7 @@ actual val deviceName: String get() = InetAddress.getLocalHost().hostName ...@@ -25,7 +25,7 @@ actual val deviceName: String get() = InetAddress.getLocalHost().hostName
* Ktor HttpClient. 不同平台使用不同引擎. * Ktor HttpClient. 不同平台使用不同引擎.
*/ */
@KtorExperimentalAPI @KtorExperimentalAPI
internal actual val httpClient: HttpClient internal actual val Http: HttpClient
get() = HttpClient(CIO) get() = HttpClient(CIO)
/** /**
......
...@@ -226,6 +226,7 @@ Mirai 22:04:48 : Packet received: UnknownEventPacket(id=00 D6, identity=(2092749 ...@@ -226,6 +226,7 @@ Mirai 22:04:48 : Packet received: UnknownEventPacket(id=00 D6, identity=(2092749
* 添加一个好友 * 添加一个好友
* *
* @param lazyMessage 若需要验证请求时的验证消息. * @param lazyMessage 若需要验证请求时的验证消息.
* @param lazyRemark 好友备注
*/ */
suspend fun ContactSystem.addFriend(id: UInt, lazyMessage: () -> String = { "" }, lazyRemark: () -> String = { "" }): AddFriendResult = bot.withSession { suspend fun ContactSystem.addFriend(id: UInt, lazyMessage: () -> String = { "" }, lazyRemark: () -> String = { "" }): AddFriendResult = bot.withSession {
when (CanAddFriendPacket(bot.qqAccount, id, bot.sessionKey).sendAndExpect<CanAddFriendResponse>()) { when (CanAddFriendPacket(bot.qqAccount, id, bot.sessionKey).sendAndExpect<CanAddFriendResponse>()) {
......
...@@ -5,7 +5,9 @@ package net.mamoe.mirai.message ...@@ -5,7 +5,9 @@ package net.mamoe.mirai.message
import net.mamoe.mirai.contact.Contact import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.contact.QQ import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.network.protocol.tim.packet.action.FriendImageIdRequestPacket import net.mamoe.mirai.network.protocol.tim.packet.action.FriendImageIdRequestPacket
import net.mamoe.mirai.network.protocol.tim.packet.action.download
import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.Http
import kotlin.js.JsName import kotlin.js.JsName
import kotlin.jvm.Volatile import kotlin.jvm.Volatile
...@@ -154,17 +156,6 @@ inline class Image(inline val id: ImageId) : Message { ...@@ -154,17 +156,6 @@ inline class Image(inline val id: ImageId) : Message {
override val stringValue: String get() = "[${id.value}]" override val stringValue: String get() = "[${id.value}]"
override fun toString(): String = stringValue override fun toString(): String = stringValue
/**
* 下载这个图片
*/
suspend fun download(): ExternalImage {
// http://101.89.39.21/offpic_new/892185277C8A24AB9BB91AE888A6BC910C4D48CBA84BBB2F0D800761F1DD2F71F205364442C451A82D2F6FAD38CF71A9D65B6873409BD10CCF22BBF7DFA73DD7DA06FBB7386E31E4/0?vuin=1040400290&term=255&srvver=26933&rf=naio
// http://61.151.234.54/offpic_new/A47CAC5D3C5EF955A77ECE13DA969A69238167886464C00FD75FFC49A76EF15A1F05ED04BC2DE91190A40048AAF97BB6DFDB25BFB0EFE6A9516DC3BE0532A9A93A87A4C8D2E9729C/0?vuin=1040400290&term=255&srvver=26933&rf=naio
TODO()
}
companion object Key : Message.Key<Image> companion object Key : Message.Key<Image>
} }
...@@ -181,7 +172,11 @@ inline class ImageId(inline val value: String) ...@@ -181,7 +172,11 @@ inline class ImageId(inline val value: String)
/** /**
* 图片数据地址. * 图片数据地址.
*/ */
inline class ImageLink(inline val value: String) inline class ImageLink(inline val value: String) {
// TODO: 2019/11/15 应添加更多方法. 避免使用 byte[]
suspend fun downloadAsByteArray(): ByteArray = Http.download(value)
}
fun ImageId.checkLength() = check(value.length == 37 || value.length == 42) { "Illegal ImageId length" } fun ImageId.checkLength() = check(value.length == 37 || value.length == 42) { "Illegal ImageId length" }
fun ImageId.requireLength() = require(value.length == 37 || value.length == 42) { "Illegal ImageId length" } fun ImageId.requireLength() = require(value.length == 37 || value.length == 42) { "Illegal ImageId length" }
......
...@@ -31,7 +31,6 @@ import kotlin.coroutines.coroutineContext ...@@ -31,7 +31,6 @@ import kotlin.coroutines.coroutineContext
*/ */
@Suppress("FunctionName", "NOTHING_TO_INLINE") @Suppress("FunctionName", "NOTHING_TO_INLINE")
internal inline fun TIMBotNetworkHandler.BotSession( internal inline fun TIMBotNetworkHandler.BotSession(
bot: Bot,
sessionKey: SessionKey, sessionKey: SessionKey,
socket: DataPacketSocketAdapter socket: DataPacketSocketAdapter
): BotSession = BotSession(bot, sessionKey, socket, this) ): BotSession = BotSession(bot, sessionKey, socket, this)
...@@ -42,7 +41,7 @@ internal inline fun TIMBotNetworkHandler.BotSession( ...@@ -42,7 +41,7 @@ internal inline fun TIMBotNetworkHandler.BotSession(
* *
* @author Him188moe * @author Him188moe
*/ */
class BotSession( data class BotSession(
val bot: Bot, val bot: Bot,
val sessionKey: SessionKey, val sessionKey: SessionKey,
val socket: DataPacketSocketAdapter, val socket: DataPacketSocketAdapter,
...@@ -105,39 +104,11 @@ class BotSession( ...@@ -105,39 +104,11 @@ class BotSession(
return deferred return deferred
} }
/**
* 发送一个数据包, 并期待接受一个特定的 [ServerPacket][P].
* 将能从本函数的返回值 [CompletableDeferred] 接收到所期待的 [P]
* 本函数将能帮助实现清晰的包处理逻辑
*
* 实现方法:
* ```kotlin
* with(session){
* val deferred = ClientPacketXXX(...).sendAndExpectAsync<ServerPacketXXX>()
* // do something
*
* deferred.await() // or deferred.join()
* }
* ```
*/
suspend inline fun <reified P : Packet> OutgoingPacket.sendAndExpectAsync(checkSequence: Boolean = true): Deferred<P> = suspend inline fun <reified P : Packet> OutgoingPacket.sendAndExpectAsync(checkSequence: Boolean = true): Deferred<P> =
sendAndExpectAsync<P, P>(checkSequence) { it } sendAndExpectAsync<P, P>(checkSequence) { it }
/** suspend inline fun <reified P : Packet, R> OutgoingPacket.sendAndExpect(checkSequence: Boolean = true, crossinline mapper: (P) -> R): R =
* 发送一个数据包, 并期待接受一个特定的 [ServerPacket][P]. sendAndExpectAsync<P, R>(checkSequence) { mapper(it) }.await()
* 将调用 [CompletableDeferred.await], 挂起等待接收到指定的包后才返回.
* 本函数将能帮助实现清晰的包处理逻辑
*
* 实现方法:
* ```kotlin
* with(session){
* val packet:AddFriendPacket.Response = AddFriendPacket(...).sendAndExpect<AddFriendPacket.Response>()
* }
* ```
* @sample Bot.addFriend 添加好友
*/
suspend inline fun <reified P : Packet, R> OutgoingPacket.sendAndExpect(checkSequence: Boolean = true, crossinline block: (P) -> R): R =
sendAndExpectAsync<P, R>(checkSequence) { block(it) }.await()
suspend inline fun <reified P : Packet> OutgoingPacket.sendAndExpect(checkSequence: Boolean = true): P = suspend inline fun <reified P : Packet> OutgoingPacket.sendAndExpect(checkSequence: Boolean = true): P =
sendAndExpectAsync<P, P>(checkSequence) { it }.await() sendAndExpectAsync<P, P>(checkSequence) { it }.await()
......
...@@ -62,7 +62,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou ...@@ -62,7 +62,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
handlersLock.withLock { handlersLock.withLock {
temporaryPacketHandlers.add(temporaryPacketHandler) temporaryPacketHandlers.add(temporaryPacketHandler)
} }
temporaryPacketHandler.send(this[ActionPacketHandler].session) temporaryPacketHandler.send(this.session)
} }
override suspend fun login(configuration: BotConfiguration): LoginResult { override suspend fun login(configuration: BotConfiguration): LoginResult {
...@@ -90,7 +90,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou ...@@ -90,7 +90,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
//private | internal //private | internal
private fun onLoggedIn() { private fun onLoggedIn() {
require(size == 0) { "Already logged in" } require(size == 0) { "Already logged in" }
val session = BotSession(bot, sessionKey, socket) val session = BotSession(sessionKey, socket)
add(ActionPacketHandler(session).asNode(ActionPacketHandler)) add(ActionPacketHandler(session).asNode(ActionPacketHandler))
bot.logger.info("Successfully logged in") bot.logger.info("Successfully logged in")
......
...@@ -36,5 +36,5 @@ internal fun <T : PacketHandler> T.asNode(key: PacketHandler.Key<T>): PacketHand ...@@ -36,5 +36,5 @@ internal fun <T : PacketHandler> T.asNode(key: PacketHandler.Key<T>): PacketHand
internal open class PacketHandlerList : MutableList<PacketHandlerNode<*>> by mutableListOf() { internal open class PacketHandlerList : MutableList<PacketHandlerNode<*>> by mutableListOf() {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
operator fun <T : PacketHandler> get(key: PacketHandler.Key<T>): T = this.first { it.key === key }.instance as T operator fun <T : PacketHandler> get(key: PacketHandler.Key<T>): T = this.first { it.key == key }.instance as T
} }
...@@ -9,11 +9,10 @@ import kotlin.reflect.KClass ...@@ -9,11 +9,10 @@ import kotlin.reflect.KClass
/** /**
* 包 ID. 除特殊外, [PacketFactory] 都需要这个注解来指定包 ID. * 包 ID. 除特殊外, [PacketFactory] 都需要这个注解来指定包 ID.
*/ */
@Deprecated("Reflection is not supported in JS. Consider to remove")
@MustBeDocumented @MustBeDocumented
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
annotation class AnnotatedId( annotation class AnnotatedId( // 注解无法在 JS 平台使用, 但现在暂不需要考虑 JS
val id: KnownPacketId val id: KnownPacketId
) )
...@@ -40,7 +39,7 @@ annotation class CorrespondingEvent( ...@@ -40,7 +39,7 @@ annotation class CorrespondingEvent(
internal annotation class PacketVersion(val date: String, val timVersion: String) internal annotation class PacketVersion(val date: String, val timVersion: String)
/** /**
* 带有这个注解的 [Packet], 将不会被记录在 log 中. * 带有这个注解的 [Packet] 将不会被记录在 log 中.
*/ */
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
......
...@@ -26,7 +26,7 @@ abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val d ...@@ -26,7 +26,7 @@ abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val d
*/ */
private val annotatedId: AnnotatedId private val annotatedId: AnnotatedId
get() = (this::class.annotations.firstOrNull { it is AnnotatedId } as? AnnotatedId) get() = (this::class.annotations.firstOrNull { it is AnnotatedId } as? AnnotatedId)
?: error("Annotation AnnotatedId not found") ?: error("Annotation AnnotatedId not found for class ${this::class.simpleName}")
/** /**
* 包 ID. * 包 ID.
......
...@@ -205,7 +205,7 @@ object AddFriendPacket : SessionPacketFactory<AddFriendPacket.Response>() { ...@@ -205,7 +205,7 @@ object AddFriendPacket : SessionPacketFactory<AddFriendPacket.Response>() {
/** /**
* 备注名 * 备注名
*/ */
remark: String, remark: String, //// TODO: 2019/11/15 无备注的情况
key: FriendAdditionKey key: FriendAdditionKey
): OutgoingPacket = buildSessionPacket(bot, sessionKey) { ): OutgoingPacket = buildSessionPacket(bot, sessionKey) {
......
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
...@@ -12,6 +12,8 @@ import net.mamoe.mirai.network.protocol.tim.TIMProtocol ...@@ -12,6 +12,8 @@ import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.* import net.mamoe.mirai.network.protocol.tim.packet.*
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
@AnnotatedId(KnownPacketId.SEND_GROUP_MESSAGE)
@PacketVersion(date = "2019.10.19", timVersion = "2.3.2 (21173)")
object SendGroupMessagePacket : SessionPacketFactory<SendGroupMessagePacket.Response>() { object SendGroupMessagePacket : SessionPacketFactory<SendGroupMessagePacket.Response>() {
operator fun invoke( operator fun invoke(
botQQ: UInt, botQQ: UInt,
......
...@@ -14,6 +14,7 @@ import kotlinx.coroutines.withContext ...@@ -14,6 +14,7 @@ import kotlinx.coroutines.withContext
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.*
import net.mamoe.mirai.message.ImageId import net.mamoe.mirai.message.ImageId
import net.mamoe.mirai.message.ImageLink
import net.mamoe.mirai.message.requireLength import net.mamoe.mirai.message.requireLength
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
...@@ -22,8 +23,8 @@ import net.mamoe.mirai.network.protocol.tim.packet.event.EventPacket ...@@ -22,8 +23,8 @@ import net.mamoe.mirai.network.protocol.tim.packet.event.EventPacket
import net.mamoe.mirai.network.qqAccount import net.mamoe.mirai.network.qqAccount
import net.mamoe.mirai.qqAccount import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.Http
import net.mamoe.mirai.utils.configureBody import net.mamoe.mirai.utils.configureBody
import net.mamoe.mirai.utils.httpClient
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.withSession import net.mamoe.mirai.withSession
import kotlin.coroutines.coroutineContext import kotlin.coroutines.coroutineContext
...@@ -47,7 +48,7 @@ suspend fun Group.uploadImage(image: ExternalImage): ImageId = withSession { ...@@ -47,7 +48,7 @@ suspend fun Group.uploadImage(image: ExternalImage): ImageId = withSession {
withContext(userContext) { withContext(userContext) {
when (response) { when (response) {
is GroupImageIdRequestPacket.Response.RequireUpload -> httpClient.postImage( is GroupImageIdRequestPacket.Response.RequireUpload -> Http.postImage(
htcmd = "0x6ff0071", htcmd = "0x6ff0071",
uin = bot.qqAccount, uin = bot.qqAccount,
groupId = GroupId(id), groupId = GroupId(id),
...@@ -79,7 +80,7 @@ suspend fun QQ.uploadImage(image: ExternalImage): ImageId = bot.withSession { ...@@ -79,7 +80,7 @@ suspend fun QQ.uploadImage(image: ExternalImage): ImageId = bot.withSession {
.sendAndExpectAsync<FriendImageIdRequestPacket.Response, ImageId> { .sendAndExpectAsync<FriendImageIdRequestPacket.Response, ImageId> {
return@sendAndExpectAsync when (it) { return@sendAndExpectAsync when (it) {
is FriendImageIdRequestPacket.Response.RequireUpload -> { is FriendImageIdRequestPacket.Response.RequireUpload -> {
httpClient.postImage( Http.postImage(
htcmd = "0x6ff0070", htcmd = "0x6ff0070",
uin = bot.qqAccount, uin = bot.qqAccount,
groupId = null, groupId = null,
...@@ -132,11 +133,11 @@ internal suspend inline fun HttpClient.postImage( ...@@ -132,11 +133,11 @@ internal suspend inline fun HttpClient.postImage(
imageInput.close() imageInput.close()
} }
internal suspend inline fun HttpClient.download( internal suspend inline fun HttpClient.download(
url: String url: String
): ByteArray = get<HttpResponse>(url).readBytes() // TODO 不知道为什么找不到 `ByteReadChannel`. ): ByteArray = get<HttpResponse>(url).readBytes() // TODO 不知道为什么找不到 `ByteReadChannel`.
/* /*
/** /**
* 似乎没有必要. 服务器的返回永远都是 01 00 00 00 02 00 00 * 似乎没有必要. 服务器的返回永远都是 01 00 00 00 02 00 00
...@@ -195,7 +196,7 @@ object SubmitImageFilenamePacket : PacketFactory { ...@@ -195,7 +196,7 @@ object SubmitImageFilenamePacket : PacketFactory {
*/ */
@AnnotatedId(KnownPacketId.FRIEND_IMAGE_ID) @AnnotatedId(KnownPacketId.FRIEND_IMAGE_ID)
@PacketVersion(date = "2019.11.14", timVersion = "2.3.2 (21173)") @PacketVersion(date = "2019.11.14", timVersion = "2.3.2 (21173)")
object FriendImageIdDownloadLinkRequestPacket : SessionPacketFactory<FriendImageIdDownloadLinkRequestPacket.DownloadLink>() { object FriendImageIdDownloadLinkRequestPacket : SessionPacketFactory<FriendImageIdDownloadLinkRequestPacket.ImageLinkResponse>() {
operator fun invoke( operator fun invoke(
bot: UInt, bot: UInt,
sessionKey: SessionKey, sessionKey: SessionKey,
...@@ -239,14 +240,14 @@ object FriendImageIdDownloadLinkRequestPacket : SessionPacketFactory<FriendImage ...@@ -239,14 +240,14 @@ object FriendImageIdDownloadLinkRequestPacket : SessionPacketFactory<FriendImage
/** /**
* 图片下载链接. 直接 'get' 请求即可 * 图片下载链接. 直接 'get' 请求即可
*/ */
data class DownloadLink( data class ImageLinkResponse(
val imageId: ImageId, val imageId: ImageId,
val link: String val link: ImageLink
) : Packet ) : Packet
// TODO: 2019/11/14 需要跟 RequestId packet 合并. 因为现行结构无法分别处理; 或者考虑修改结构(不推荐) // TODO: 2019/11/14 需要跟 RequestId packet 合并. 因为现行结构无法分别处理; 或者考虑修改结构(不推荐)
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): DownloadLink { override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): ImageLinkResponse {
//00 00 00 08 00 00 //00 00 00 08 00 00
// [02 2B] // [02 2B]
// 12 [06] 98 01 02 A0 01 00 // 12 [06] 98 01 02 A0 01 00
...@@ -282,7 +283,7 @@ object FriendImageIdDownloadLinkRequestPacket : SessionPacketFactory<FriendImage ...@@ -282,7 +283,7 @@ object FriendImageIdDownloadLinkRequestPacket : SessionPacketFactory<FriendImage
val link = readUVarIntLVString() val link = readUVarIntLVString()
discard() discard()
return DownloadLink(imageId, link) return ImageLinkResponse(imageId, ImageLink(link))
} }
} }
......
...@@ -147,7 +147,7 @@ object SubmitPasswordPacket : PacketFactory<SubmitPasswordPacket.LoginResponse, ...@@ -147,7 +147,7 @@ object SubmitPasswordPacket : PacketFactory<SubmitPasswordPacket.LoginResponse,
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): LoginResponse { override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): LoginResponse {
val size = remaining.toInt() val size = remaining.toInt()
return when { return when {
size == 229 || size == 271 || size == 207 -> { size == 229 || size == 271 || size == 207 || size == 165 /* TODO CHECK 165 */ -> {
discardExact(5)//01 00 1E 00 10 discardExact(5)//01 00 1E 00 10
val privateKeyUpdate = PrivateKey(readBytes(0x10)) val privateKeyUpdate = PrivateKey(readBytes(0x10))
discardExact(4)//00 06 00 78 discardExact(4)//00 06 00 78
...@@ -243,6 +243,8 @@ object SubmitPasswordPacket : PacketFactory<SubmitPasswordPacket.LoginResponse, ...@@ -243,6 +243,8 @@ object SubmitPasswordPacket : PacketFactory<SubmitPasswordPacket.LoginResponse,
279, 495, 551, 487 -> LoginResult.DEVICE_LOCK 279, 495, 551, 487 -> LoginResult.DEVICE_LOCK
343, 359 -> LoginResult.TAKEN_BACK 343, 359 -> LoginResult.TAKEN_BACK
// 165: 01 00 1E 00 10 72 36 7B 6B 6D 78 3A 4B 63 7B 47 5B 68 3E 21 59 00 06 00 78 34 F6 F9 49 AA 13 F5 F5 01 36 13 E1 4C F7 0F 25 C1 2C 10 75 CA 69 E9 12 B3 6D F4 A7 59 60 FF 01 03 73 28 47 A3 2A B8 46 C3 92 24 D5 8A AE 8B C2 45 0C 31 27 B5 17 9E 22 13 59 AF B4 CC F6 E3 3A 91 60 13 21 11 3C 25 D9 50 F4 23 C6 06 1D F4 15 41 BA 5D 7B 66 26 96 EB 0E 04 14 8E 5B D4 33 6E B8 5D E7 10 3A 0E EF 96 B1 D4 22 E4 74 48 A7 1D 3A 46 7D E6 EF 1F 6B 69 01 15 00 10 6F 99 48 5E 98 AE D3 4B F8 35 63 1D 70 EE 6D 82
else -> { else -> {
MiraiLogger.error("login response packet size = $size, data=${this.readRemainingBytes().toUHexString()}") MiraiLogger.error("login response packet size = $size, data=${this.readRemainingBytes().toUHexString()}")
LoginResult.UNKNOWN LoginResult.UNKNOWN
......
...@@ -43,7 +43,7 @@ expect fun localIpAddress(): String ...@@ -43,7 +43,7 @@ expect fun localIpAddress(): String
/** /**
* Ktor HttpClient. 不同平台使用不同引擎. * Ktor HttpClient. 不同平台使用不同引擎.
*/ */
internal expect val httpClient: HttpClient internal expect val Http: HttpClient
// FIXME: 2019/10/28 这个方法不是很好的实现 // FIXME: 2019/10/28 这个方法不是很好的实现
......
...@@ -55,7 +55,7 @@ actual fun solveIpAddress(hostname: String): String = InetAddress.getByName(host ...@@ -55,7 +55,7 @@ actual fun solveIpAddress(hostname: String): String = InetAddress.getByName(host
actual fun localIpAddress(): String = InetAddress.getLocalHost().hostAddress actual fun localIpAddress(): String = InetAddress.getLocalHost().hostAddress
internal actual val httpClient: HttpClient = HttpClient(CIO) internal actual val Http: HttpClient = HttpClient(CIO)
internal actual fun HttpRequestBuilder.configureBody( internal actual fun HttpRequestBuilder.configureBody(
inputSize: Long, inputSize: Long,
......
...@@ -9,6 +9,8 @@ dependencies { ...@@ -9,6 +9,8 @@ dependencies {
api group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlin_version api group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlin_version
api group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: coroutines_version api group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: coroutines_version
implementation("org.jetbrains.kotlinx:kotlinx-io:$kotlinxio_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-io:$coroutinesio_version")
compile group: 'com.alibaba', name: 'fastjson', version: '1.2.62' compile group: 'com.alibaba', name: 'fastjson', version: '1.2.62'
implementation 'org.jsoup:jsoup:1.12.1' implementation 'org.jsoup:jsoup:1.12.1'
} }
......
...@@ -2,9 +2,11 @@ ...@@ -2,9 +2,11 @@
package demo.gentleman package demo.gentleman
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.BotAccount import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.addFriend import net.mamoe.mirai.addFriend
...@@ -12,7 +14,11 @@ import net.mamoe.mirai.event.Subscribable ...@@ -12,7 +14,11 @@ 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.login import net.mamoe.mirai.login
import net.mamoe.mirai.message.Image
import net.mamoe.mirai.network.protocol.tim.packet.action.downloadAsByteArray
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 java.io.File import java.io.File
import kotlin.random.Random import kotlin.random.Random
...@@ -52,22 +58,24 @@ suspend fun main() { ...@@ -52,22 +58,24 @@ suspend fun main() {
sender.profile.await().toString() sender.profile.await().toString()
} }
/*
has<Image> { has<Image> {
reply(message) if (this is FriendMessage) {
}*/ withContext(IO) {
reply(message[Image] + " downloading")
sender.downloadAsByteArray(message[Image]).inputStream()
.transferTo(File(System.getProperty("user.dir", "testDownloadedImage${currentTime}.png")).outputStream())
reply(message[Image] + " downloaded")
}
}
}
startsWith("随机图片", removePrefix = true) { startsWith("随机图片", removePrefix = true) {
try {
repeat(it.toIntOrNull() ?: 1) { repeat(it.toIntOrNull() ?: 1) {
GlobalScope.launch { GlobalScope.launch {
delay(Random.Default.nextLong(100, 1000)) delay(Random.Default.nextLong(100, 1000))
Gentlemen.provide(subject).receive().image.await().send() Gentlemen.provide(subject).receive().image.await().send()
} }
} }
} catch (e: Exception) {
reply(e.message ?: "exception: null")
}
} }
startsWith("添加好友", removePrefix = true) { startsWith("添加好友", removePrefix = true) {
......
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