From 0dbbbbb51dc0e90da99de9050976df8b51e58fc5 Mon Sep 17 00:00:00 2001 From: Him188 Date: Wed, 4 Mar 2020 22:57:36 +0800 Subject: [PATCH] Fix loadClass --- gradle/wrapper/gradle-wrapper.properties | 4 +- mirai-console/build.gradle.kts | 2 +- .../mirai/console/core/MiraiCoreLoader.kt | 119 +++++++++--------- 3 files changed, 66 insertions(+), 59 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 64f0fd9b7..a47f646fb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ -#Thu Feb 27 13:09:44 CST 2020 -distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-bin.zip +#Wed Mar 04 22:27:09 CST 2020 +distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists diff --git a/mirai-console/build.gradle.kts b/mirai-console/build.gradle.kts index 8f7b468d5..f55755310 100644 --- a/mirai-console/build.gradle.kts +++ b/mirai-console/build.gradle.kts @@ -37,7 +37,7 @@ val miraiVersion: String by rootProject.ext dependencies { compileOnly("net.mamoe:mirai-core-jvm:$miraiVersion") - compileOnly("net.mamoe:mirai-core-qqandroid-jvm:$miraiVersion") + // compileOnly("net.mamoe:mirai-core-qqandroid-jvm:$miraiVersion") api(kotlin("serialization")) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/core/MiraiCoreLoader.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/core/MiraiCoreLoader.kt index a07eeec54..cae6aa608 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/core/MiraiCoreLoader.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/core/MiraiCoreLoader.kt @@ -1,3 +1,12 @@ +/* + * Copyright 2020 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + package net.mamoe.mirai.console.core import io.ktor.client.HttpClient @@ -6,20 +15,21 @@ import io.ktor.client.request.get import io.ktor.client.request.url import io.ktor.client.statement.HttpResponse import io.ktor.http.URLProtocol +import io.ktor.util.KtorExperimentalAPI import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.jvm.javaio.copyTo import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import net.mamoe.mirai.console.MiraiConsole - import java.io.File import java.net.URLClassLoader import kotlin.math.pow import kotlin.system.exitProcess -@Suppress("EXPERIMENTAL_API_USAGE") -val Http: HttpClient get() = HttpClient(CIO) +@UseExperimental(KtorExperimentalAPI::class) +val Http: HttpClient + get() = HttpClient(CIO) object MiraiCoreLoader { val coresPath by lazy { @@ -30,7 +40,7 @@ object MiraiCoreLoader { } } - private fun getProtocolLib():File?{ + private fun getProtocolLib(): File? { this.coresPath.listFiles()?.forEach { file -> if (file != null && file.extension == "jar" && file.name.contains("qqandroid")) { return file @@ -39,7 +49,7 @@ object MiraiCoreLoader { return null } - private fun getCore():File?{ + private fun getCore(): File? { this.coresPath.listFiles()?.forEach { file -> if (file != null && file.extension == "jar" && file.name.contains("core") && (!file.name.contains("qqandroid"))) { return file @@ -49,14 +59,14 @@ object MiraiCoreLoader { } - operator fun invoke():String{ + operator fun invoke(): String { MiraiConsole.logger("Fetching Newest Core Version .. ") val newest = runBlocking { getNewestVersion() } val current = getCurrentVersion() MiraiConsole.logger("Local Version: $current | Newest Version: $newest") - if(current != newest){ + if (current != newest) { MiraiConsole.logger("Updating from V$current -> V$newest, this is a force update") cleanCoreAndLib() runBlocking { @@ -77,21 +87,21 @@ object MiraiCoreLoader { private suspend fun getNewestVersion(): String { try { return """>([0-9])*\.([0-9])*\.([0-9])*/""".toRegex().findAll( - Http.get { - url { - protocol = URLProtocol.HTTPS - host = "jcenter.bintray.com" - path("net/mamoe/mirai-core-qqandroid-jvm/") + Http.get { + url { + protocol = URLProtocol.HTTPS + host = "jcenter.bintray.com" + path("net/mamoe/mirai-core-qqandroid-jvm/") + } } - } - ).asSequence() + ).asSequence() .map { it.value.drop(1).dropLast(1) } .maxBy { it.split('.').foldRightIndexed(0) { index: Int, s: String, acc: Int -> acc + 100.0.pow(index).toInt() + (s.toIntOrNull() ?: 0) } }!! - }catch (e:Exception){ + } catch (e: Exception) { MiraiConsole.logger("Failed to fetch newest Core version, please seek for help") e.printStackTrace() MiraiConsole.logger("Failed to fetch newest Core version, please seek for help") @@ -103,18 +113,18 @@ object MiraiCoreLoader { * 使用Protocol Lib判断当前版本 * 如果没有 会返回0.0.0 * */ - private fun getCurrentVersion():String{ - val file = getProtocolLib() - if(file == null || getCore() == null)return "0.0.0" + private fun getCurrentVersion(): String { + val file = getProtocolLib() + if (file == null || getCore() == null) return "0.0.0" val numberVersion = """([0-9])*\.([0-9])*\.([0-9])*""".toRegex().find(file.name)?.value - if(numberVersion != null) { + if (numberVersion != null) { return numberVersion + file.name.substringAfter(numberVersion).substringBefore(".jar") } return "0.0.0" } - private fun cleanCoreAndLib(){ + private fun cleanCoreAndLib() { this.coresPath.listFiles()?.forEach { if (it != null && it.extension == "jar") { it.delete() @@ -123,34 +133,36 @@ object MiraiCoreLoader { } - - val lib_jcenter = "https://jcenter.bintray.com/net/mamoe/mirai-core-qqandroid-jvm/{version}/:mirai-core-qqandroid-jvm-{version}.jar" - val lib_aliyun = "https://maven.aliyun.com/nexus/content/repositories/jcenter/net/mamoe/mirai-core-qqandroid-jvm/{version}/mirai-core-qqandroid-jvm-{version}.jar" + val lib_jcenter = + "https://jcenter.bintray.com/net/mamoe/mirai-core-qqandroid-jvm/{version}/:mirai-core-qqandroid-jvm-{version}.jar" + val lib_aliyun = + "https://maven.aliyun.com/nexus/content/repositories/jcenter/net/mamoe/mirai-core-qqandroid-jvm/{version}/mirai-core-qqandroid-jvm-{version}.jar" val core_jcenter = "https://jcenter.bintray.com/net/mamoe/mirai-core-jvm/{version}/:mirai-core-jvm-{version}.jar" - val core_aliyun = "https://maven.aliyun.com/nexus/content/repositories/jcenter/net/mamoe/mirai-core-jvm/{version}/mirai-core-jvm-{version}.jar" + val core_aliyun = + "https://maven.aliyun.com/nexus/content/repositories/jcenter/net/mamoe/mirai-core-jvm/{version}/mirai-core-jvm-{version}.jar" - private suspend fun downloadCoreAndLib(version:String){ - var fileStream = File(coresPath.absolutePath + "/" + "mirai-core-qqandroid-jvm-$version.jar").also{ + private suspend fun downloadCoreAndLib(version: String) { + var fileStream = File(coresPath.absolutePath + "/" + "mirai-core-qqandroid-jvm-$version.jar").also { withContext(Dispatchers.IO) { it.createNewFile() } }.outputStream() - suspend fun downloadRequest(url:String, version:String):ByteReadChannel{ - return Http.get(){ - this.url(url.replace("{version}",version)) + suspend fun downloadRequest(url: String, version: String): ByteReadChannel { + return Http.get() { + this.url(url.replace("{version}", version)) }.content } - var stream = try{ + var stream = try { MiraiConsole.logger("Downloading newest Protocol lib from Aliyun") - downloadRequest(lib_aliyun,version) - }catch (ignored:Exception){ - try{ + downloadRequest(lib_aliyun, version) + } catch (ignored: Exception) { + try { MiraiConsole.logger("Downloading newest Protocol lib from JCenter") - downloadRequest(lib_jcenter,version) - }catch (e:Exception){ + downloadRequest(lib_jcenter, version) + } catch (e: Exception) { MiraiConsole.logger("Failed to download Protocol lib, please seeking for help") e.printStackTrace() MiraiConsole.logger("Failed to download Protocol lib, please seeking for help") @@ -163,21 +175,21 @@ object MiraiCoreLoader { fileStream.flush() } - fileStream = File(coresPath.absolutePath + "/" + "mirai-core-jvm-$version.jar").also{ + fileStream = File(coresPath.absolutePath + "/" + "mirai-core-jvm-$version.jar").also { withContext(Dispatchers.IO) { it.createNewFile() } }.outputStream() - stream = try{ + stream = try { MiraiConsole.logger("Downloading newest Mirai Core from Aliyun") - downloadRequest(core_aliyun,version) - }catch (ignored:Exception){ - try{ + downloadRequest(core_aliyun, version) + } catch (ignored: Exception) { + try { MiraiConsole.logger("Downloading newest Mirai Core from JCenter") - downloadRequest(core_jcenter,version) - }catch (e:Exception){ + downloadRequest(core_jcenter, version) + } catch (e: Exception) { MiraiConsole.logger("Failed to download Mirai Core, please seeking for help") e.printStackTrace() MiraiConsole.logger("Failed to download Mirai Core, please seeking for help") @@ -192,24 +204,19 @@ object MiraiCoreLoader { } - private fun loadCoreAndLib(){ + private fun loadCoreAndLib() { try { - MiraiConsole.logger("Core:" + getCore()) - MiraiConsole.logger("Protocol:" + getProtocolLib()) + MiraiConsole.logger("Core: " + getCore()) + MiraiConsole.logger("Protocol: " + getProtocolLib()) - MiraiCoreClassLoader( - (getCore()!!), - this.javaClass.classLoader + + val classloader = URLClassLoader( + arrayOf(getCore()!!.toURI().toURL(), getProtocolLib()!!.toURI().toURL()), + Thread.currentThread().contextClassLoader ) - .loadClass("net.mamoe.mirai.BotFactory") - - - MiraiCoreClassLoader( - (getProtocolLib()!!), - this.javaClass.classLoader - ) - .loadClass("net.mamoe.mirai.qqandroid.QQAndroid") + println(classloader.loadClass("net.mamoe.mirai.BotFactory")) + println(classloader.loadClass("net.mamoe.mirai.qqandroid.QQAndroid")) } catch (e: ClassNotFoundException) { MiraiConsole.logger("Failed to load core, please seek for help")