From afb14f5699f25fea3f57f6db7e3941573014cf7c Mon Sep 17 00:00:00 2001 From: cssxsh Date: Thu, 10 Nov 2022 21:41:10 +0800 Subject: [PATCH] fix: 2.13.0 (#168) * fix: 2.13.0 * fix: ContentType --- build.gradle.kts | 36 ++++++++-------- .../org/itxtech/mirainative/MiraiNative.kt | 10 ++--- .../bridge/ForwardMessageDecoder.kt | 1 - .../itxtech/mirainative/bridge/MiraiBridge.kt | 42 ++++++++++--------- .../mirainative/manager/CacheManager.kt | 2 - .../mirainative/message/ChainCodeConverter.kt | 5 ++- .../org/itxtech/mirainative/util/Music.kt | 11 ++--- 7 files changed, 53 insertions(+), 54 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index c3ba915..e3c042f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,33 +1,31 @@ plugins { - id("me.him188.maven-central-publish") version "1.0.0-dev-3" - - kotlin("jvm") version "1.6.0" - kotlin("plugin.serialization") version "1.6.20-RC" + kotlin("jvm") version "1.7.20" + kotlin("plugin.serialization") version "1.7.20" - id("net.mamoe.mirai-console") version "2.11.0-M1" + id("me.him188.maven-central-publish") version "1.0.0-dev-3" + id("net.mamoe.mirai-console") version "2.13.0-RC2" } group = "org.itxtech" version = "2.0.0" description = "强大的 mirai 原生插件加载器。" -kotlin { - sourceSets { - all { - languageSettings.enableLanguageFeature("InlineClasses") - languageSettings.optIn("kotlin.Experimental") - } - } -} - repositories { mavenCentral() - maven("https://maven.aliyun.com/repository/public") } dependencies { - compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.2") - compileOnly("org.jetbrains.kotlinx:atomicfu:0.17.0") + compileOnly("org.jetbrains.kotlinx:atomicfu:0.18.4") + implementation("io.ktor:ktor-client-okhttp:2.1.3") { + exclude(group = "org.jetbrains.kotlin") + exclude(group = "org.jetbrains.kotlinx") + exclude(group = "org.slf4j") + } + implementation("com.squareup.okhttp3:okhttp:4.10.0") { + exclude(group = "org.jetbrains.kotlin") + exclude(group = "org.jetbrains.kotlinx") + exclude(group = "org.slf4j") + } } mavenCentralPublish { @@ -44,6 +42,6 @@ tasks.named("jar") { } } -tasks.withType { - kotlinOptions.jvmTarget = "11" +mirai { + jvmTarget = JavaVersion.VERSION_11 } diff --git a/src/main/kotlin/org/itxtech/mirainative/MiraiNative.kt b/src/main/kotlin/org/itxtech/mirainative/MiraiNative.kt index 5180b96..3096ec6 100644 --- a/src/main/kotlin/org/itxtech/mirainative/MiraiNative.kt +++ b/src/main/kotlin/org/itxtech/mirainative/MiraiNative.kt @@ -44,10 +44,11 @@ import java.io.File import java.io.FileOutputStream import java.math.BigInteger import java.security.MessageDigest +import java.util.* import java.util.jar.Manifest object MiraiNative : KotlinPlugin( - JvmPluginDescriptionBuilder("MiraiNative", "2.0.0-beta.2") + JvmPluginDescriptionBuilder("MiraiNative", "2.0.0") .id("org.itxtech.mirainative") .author("iTX Technologies") .info("强大的 mirai 原生插件加载器。") @@ -58,13 +59,13 @@ object MiraiNative : KotlinPlugin( val imageDataPath: File by lazy { File("data" + File.separatorChar + "image").also { it.mkdirs() } } val recDataPath: File by lazy { File("data" + File.separatorChar + "record").also { it.mkdirs() } } - @OptIn(ObsoleteCoroutinesApi::class) + @OptIn(DelicateCoroutinesApi::class) private val dispatcher = newSingleThreadContext("MiraiNative Main") + SupervisorJob() - @OptIn(ObsoleteCoroutinesApi::class) + @OptIn(DelicateCoroutinesApi::class) val menuDispatcher = newSingleThreadContext("MiraiNative Menu") - @OptIn(ObsoleteCoroutinesApi::class) + @OptIn(DelicateCoroutinesApi::class) val eventDispatcher = newFixedThreadPoolContext(Runtime.getRuntime().availableProcessors() * 2, "MiraiNative Events") @@ -138,7 +139,6 @@ object MiraiNative : KotlinPlugin( File(recDataPath, "MIRAI_NATIVE_RECORD_DATA").createNewFile() } - @OptIn(InternalAPI::class) fun getDataFile(type: String, name: String): ExternalResource? { if (name.startsWith("base64://")) { return name.split("base64://", limit = 2)[1].decodeBase64Bytes().toExternalResource() diff --git a/src/main/kotlin/org/itxtech/mirainative/bridge/ForwardMessageDecoder.kt b/src/main/kotlin/org/itxtech/mirainative/bridge/ForwardMessageDecoder.kt index b06c124..18ca3a2 100644 --- a/src/main/kotlin/org/itxtech/mirainative/bridge/ForwardMessageDecoder.kt +++ b/src/main/kotlin/org/itxtech/mirainative/bridge/ForwardMessageDecoder.kt @@ -39,7 +39,6 @@ import org.itxtech.mirainative.MiraiNative import org.itxtech.mirainative.bridge.MiraiBridge.readString import org.itxtech.mirainative.message.ChainCodeConverter -@OptIn(InternalAPI::class, MiraiExperimentalApi::class) object ForwardMessageDecoder { /** * 结构 diff --git a/src/main/kotlin/org/itxtech/mirainative/bridge/MiraiBridge.kt b/src/main/kotlin/org/itxtech/mirainative/bridge/MiraiBridge.kt index f970878..cf5c872 100644 --- a/src/main/kotlin/org/itxtech/mirainative/bridge/MiraiBridge.kt +++ b/src/main/kotlin/org/itxtech/mirainative/bridge/MiraiBridge.kt @@ -26,7 +26,7 @@ package org.itxtech.mirainative.bridge import io.ktor.client.* import io.ktor.client.engine.okhttp.* -import io.ktor.client.features.* +import io.ktor.client.plugins.* import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* @@ -34,7 +34,6 @@ import io.ktor.util.* import io.ktor.util.cio.* import io.ktor.utils.io.* import io.ktor.utils.io.core.* -import io.ktor.utils.io.jvm.javaio.* import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import net.mamoe.mirai.Mirai @@ -45,7 +44,6 @@ import net.mamoe.mirai.event.events.MemberJoinRequestEvent import net.mamoe.mirai.event.events.NewFriendRequestEvent import net.mamoe.mirai.message.data.Image import net.mamoe.mirai.message.data.Image.Key.queryUrl -import net.mamoe.mirai.utils.MiraiExperimentalApi import org.itxtech.mirainative.Bridge import org.itxtech.mirainative.MiraiNative import org.itxtech.mirainative.fromNative @@ -58,13 +56,11 @@ import org.itxtech.mirainative.toNative import org.itxtech.mirainative.util.ConfigMan import java.io.File import java.math.BigInteger -import java.net.URLConnection import java.nio.charset.Charset import java.security.MessageDigest import kotlin.io.use import kotlin.text.toByteArray -@OptIn(InternalAPI::class, MiraiExperimentalApi::class) object MiraiBridge { val client = HttpClient(OkHttp) { install(UserAgent) { @@ -309,14 +305,13 @@ object MiraiBridge { val img = image.replace(".mnimg,type=flash","").replace(".mnimg", "") // fix when get flash image val u = Image(img).queryUrl() if (u != "") { - val response = client.get(u) - if (response.status.isSuccess()) { - val md = MessageDigest.getInstance("MD5") - val basename = MiraiNative.imageDataPath.absolutePath + File.separatorChar + + client.prepareGet(u).execute { response -> + if (response.status.isSuccess()) { + val md = MessageDigest.getInstance("MD5") + val basename = MiraiNative.imageDataPath.absolutePath + File.separatorChar + BigInteger(1, md.digest(img.toByteArray())) .toString(16).padStart(32, '0') - val ext = response.content.toInputStream().use { - when (URLConnection.guessContentTypeFromStream(it)) { + val ext = when (response.headers[HttpHeaders.ContentType]) { "image/gif" -> "gif" "image/png" -> "png" "image/jpeg" -> "jpg" @@ -324,13 +319,16 @@ object MiraiBridge { "image/tiff" -> "tiff" else -> "jpg" } + val file = File("$basename.$ext") + response.bodyAsChannel().copyAndClose(file.writeChannel()) + file.absolutePath + } else { + "" } - val file = File("$basename.$ext") - response.content.copyAndClose(file.writeChannel()) - return@runBlocking file.absolutePath } + } else { + "" } - return@runBlocking "" } } @@ -344,13 +342,17 @@ object MiraiBridge { BigInteger(1, rec.fileMd5).toString(16) .padStart(32, '0') + ".silk" ) - val response = client.get(rec.urlForDownload) - if (response.status.isSuccess()) { - response.content.copyAndClose(file.writeChannel()) - return@runBlocking file.absolutePath + client.prepareGet(rec.urlForDownload).execute { response -> + if (response.status.isSuccess()) { + response.bodyAsChannel().copyAndClose(file.writeChannel()) + file.absolutePath + } else { + "" + } } + } else { + "" } - return@runBlocking "" } } diff --git a/src/main/kotlin/org/itxtech/mirainative/manager/CacheManager.kt b/src/main/kotlin/org/itxtech/mirainative/manager/CacheManager.kt index 39ffbbd..bbc51df 100644 --- a/src/main/kotlin/org/itxtech/mirainative/manager/CacheManager.kt +++ b/src/main/kotlin/org/itxtech/mirainative/manager/CacheManager.kt @@ -38,7 +38,6 @@ import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource.Key.recall import net.mamoe.mirai.message.data.OnlineAudio import net.mamoe.mirai.message.data.source -import net.mamoe.mirai.utils.MiraiExperimentalApi import org.itxtech.mirainative.MiraiNative class CacheWrapper( @@ -58,7 +57,6 @@ inline fun MutableMap>.checkExpiration(exp: Int) { values.removeIf { it.creationTime + exp >= System.currentTimeMillis() } } -@OptIn(MiraiExperimentalApi::class) object CacheManager { private val msgCache = hashMapWrapperOf() private val evCache = hashMapWrapperOf() diff --git a/src/main/kotlin/org/itxtech/mirainative/message/ChainCodeConverter.kt b/src/main/kotlin/org/itxtech/mirainative/message/ChainCodeConverter.kt index 717f7e1..cb6ee07 100644 --- a/src/main/kotlin/org/itxtech/mirainative/message/ChainCodeConverter.kt +++ b/src/main/kotlin/org/itxtech/mirainative/message/ChainCodeConverter.kt @@ -24,6 +24,7 @@ package org.itxtech.mirainative.message +import io.ktor.client.call.* import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.util.* @@ -69,7 +70,7 @@ object ChainCodeConverter { } private suspend inline fun String.useExternalResource(block: (ExternalResource) -> T): T { - return MiraiBridge.client.get(this).content.toByteArray().toExternalResource().use(block) + return MiraiBridge.client.get(this).body().toExternalResource().use(block) } private suspend fun String.toMessageInternal(contact: Contact?): Message { @@ -234,8 +235,8 @@ object ChainCodeConverter { is Audio -> "[CQ:record,file=${it.filename}.mnrec]" is PokeMessage -> "[CQ:poke,id=${it.id},type=${it.pokeType},name=${it.name}]" is FlashImage -> "[CQ:image,file=${it.image.imageId}.mnimg,type=flash]" - is MarketFace -> "[CQ:bface,id=${it.id},name=${it.name}]" is Dice -> "[CQ:dice,type=${it.value}]" + is MarketFace -> "[CQ:bface,id=${it.id},name=${it.name}]" else -> ""//error("不支持的消息类型:${it::class.simpleName}") } } diff --git a/src/main/kotlin/org/itxtech/mirainative/util/Music.kt b/src/main/kotlin/org/itxtech/mirainative/util/Music.kt index 96ab4ce..961b548 100644 --- a/src/main/kotlin/org/itxtech/mirainative/util/Music.kt +++ b/src/main/kotlin/org/itxtech/mirainative/util/Music.kt @@ -25,6 +25,7 @@ package org.itxtech.mirainative.util import io.ktor.client.request.* +import io.ktor.client.statement.* import kotlinx.serialization.json.* import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.MusicKind @@ -59,15 +60,15 @@ object Music { object QQMusic : MusicProvider() { suspend fun search(name: String, page: Int, cnt: Int): JsonElement { val result = - http.get("https://c.y.qq.com/soso/fcgi-bin/client_search_cp?aggr=1&cr=1&flag_qc=0&p=$page&n=$cnt&w=$name") + http.get("https://c.y.qq.com/soso/fcgi-bin/client_search_cp?aggr=1&cr=1&flag_qc=0&p=$page&n=$cnt&w=$name").bodyAsText() return Json.parseToJsonElement(result.substring(8, result.length - 1)) } suspend fun getPlayUrl(mid: String): String { - val result = http.get( + val result = http.get( "https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?&jsonpCallback=MusicJsonCallback&cid=205361747&songmid=" + mid + "&filename=C400" + mid + ".m4a&guid=7549058080" - ) + ).bodyAsText() val json = Json.parseToJsonElement(result).jsonObject.getValue("data").jsonObject.getValue("items").jsonArray[0].jsonObject if (json["subcode"]?.jsonPrimitive?.int == 0) { @@ -77,12 +78,12 @@ object QQMusic : MusicProvider() { } suspend fun getSongInfo(id: String = "", mid: String = ""): JsonObject { - val result = http.get( + val result = http.get( "https://u.y.qq.com/cgi-bin/musicu.fcg?format=json&inCharset=utf8&outCharset=utf-8¬ice=0&" + "platform=yqq.json&needNewCode=0&data=" + "{%22comm%22:{%22ct%22:24,%22cv%22:0},%22songinfo%22:{%22method%22:%22get_song_detail_yqq%22,%22param%22:" + "{%22song_type%22:0,%22song_mid%22:%22$mid%22,%22song_id%22:$id},%22module%22:%22music.pf_song_detail_svr%22}}" - ) + ).bodyAsText() return Json.parseToJsonElement(result).jsonObject.getValue("songinfo").jsonObject.getValue("data").jsonObject }