mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-10 16:56:56 +08:00
console wrapper
This commit is contained in:
parent
9c69fb1342
commit
964db6be50
@ -0,0 +1,117 @@
|
||||
package net.mamoe.mirai.console.wrapper
|
||||
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.http.URLProtocol
|
||||
import io.ktor.utils.io.ByteReadChannel
|
||||
import io.ktor.utils.io.jvm.javaio.copyTo
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import kotlin.math.pow
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
const val CONSOLE_PURE = "Pure"
|
||||
|
||||
object ConsoleUpdator{
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private object Links:HashMap<String,Map<String,String>>() {
|
||||
init {
|
||||
put(CONSOLE_PURE, mapOf(
|
||||
"version" to "/net/mamoe/mirai-console/",
|
||||
"jcenter" to "https://jcenter.bintray.com/net/mamoe/mirai-console/{version}/:mirai-console-{version}.jar",
|
||||
"aliyun" to "https://maven.aliyun.com/nexus/content/repositories/jcenter/net/mamoe/mirai-console/{version}/mirai-console-{version}.jar"
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
var consoleType = CONSOLE_PURE
|
||||
|
||||
fun getFile():File?{
|
||||
contentPath.listFiles()?.forEach { file ->
|
||||
if (file != null && file.extension == "jar") {
|
||||
if(file.name.contains("mirai-console")) {
|
||||
when (consoleType) {
|
||||
CONSOLE_PURE -> {
|
||||
return file
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
suspend fun versionCheck(type:String) {
|
||||
this.consoleType = type
|
||||
println("Fetching Newest Console Version of $type")
|
||||
val newest = getNewestVersion()
|
||||
val current = getCurrentVersion()
|
||||
println("Local Console-$type Version: $current | Newest Console-$type Version: $newest")
|
||||
if (current != newest) {
|
||||
println("Updating Console-$type from V$current -> V$newest, this is a force update")
|
||||
this.getFile()?.delete()
|
||||
downloadConsole(newest)
|
||||
println("Download Console complete")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private suspend fun getNewestVersion():String{
|
||||
try {
|
||||
return """>([0-9])*\.([0-9])*\.([0-9])*/""".toRegex().findAll(
|
||||
Http.get<String> {
|
||||
url {
|
||||
protocol = URLProtocol.HTTPS
|
||||
host = "jcenter.bintray.com"
|
||||
path(Links[consoleType]!!["version"] ?: error("Unknown Console Type"))
|
||||
}
|
||||
}
|
||||
).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) {
|
||||
println("Failed to fetch newest Console version, please seek for help")
|
||||
e.printStackTrace()
|
||||
println("Failed to fetch newest Console version, please seek for help")
|
||||
exitProcess(1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCurrentVersion():String{
|
||||
val file = getFile()
|
||||
if(file != null) {
|
||||
val numberVersion = """([0-9])*\.([0-9])*\.([0-9])*""".toRegex().find(file.name)?.value
|
||||
if (numberVersion != null) {
|
||||
return numberVersion + file.name.substringAfter(numberVersion).substringBefore(".jar")
|
||||
}
|
||||
}
|
||||
return "0.0.0"
|
||||
}
|
||||
|
||||
private suspend fun downloadConsole(version:String){
|
||||
tryNTimesOrQuit(3) {
|
||||
kotlin.runCatching {
|
||||
println("Downloading newest Console from Aliyun")
|
||||
Http.downloadRequest(Links[consoleType]!!["aliyun"] ?: error("Unknown Console Type"), version)
|
||||
}.getOrElse {
|
||||
println("Downloading newest Console from JCenter")
|
||||
Http.downloadRequest(Links[consoleType]!!["jcenter"] ?: error("Unknown Console Type"), version)
|
||||
}
|
||||
.saveTo(if (consoleType == CONSOLE_PURE) {
|
||||
"mirai-console-$version.jar"
|
||||
} else {
|
||||
"mirai-console-$consoleType-$version.jar"
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -9,38 +9,23 @@
|
||||
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
|
||||
package net.mamoe.mirai.console.core
|
||||
package net.mamoe.mirai.console.wrapper
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.cio.CIO
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.http.URLProtocol
|
||||
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 kotlinx.coroutines.*
|
||||
import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
import kotlin.math.pow
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
val Http: HttpClient
|
||||
get() = HttpClient(CIO)
|
||||
object CoreUpdator {
|
||||
|
||||
object MiraiCoreLoader {
|
||||
private val coresPath by lazy {
|
||||
File(System.getProperty("user.dir") + "/core/").also {
|
||||
if (!it.exists()) {
|
||||
it.mkdirs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getProtocolLib(): File? {
|
||||
this.coresPath.listFiles()?.forEach { file ->
|
||||
fun getProtocolLib(): File? {
|
||||
contentPath.listFiles()?.forEach { file ->
|
||||
if (file != null && file.extension == "jar" && file.name.contains("qqandroid")) {
|
||||
return file
|
||||
}
|
||||
@ -48,8 +33,8 @@ object MiraiCoreLoader {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getCore(): File? {
|
||||
this.coresPath.listFiles()?.forEach { file ->
|
||||
fun getCore(): File? {
|
||||
contentPath.listFiles()?.forEach { file ->
|
||||
if (file != null && file.extension == "jar" && file.name.contains("core") && (!file.name.contains("qqandroid"))) {
|
||||
return file
|
||||
}
|
||||
@ -58,27 +43,24 @@ object MiraiCoreLoader {
|
||||
}
|
||||
|
||||
|
||||
fun loadCore(): String {
|
||||
MiraiConsole.logger("Fetching Newest Core Version .. ")
|
||||
val newest = runBlocking {
|
||||
getNewestVersion()
|
||||
}
|
||||
suspend fun versionCheck(){
|
||||
println("Fetching Newest Core Version .. ")
|
||||
val newest = getNewestVersion()
|
||||
val current = getCurrentVersion()
|
||||
MiraiConsole.logger("Local Version: $current | Newest Version: $newest")
|
||||
println("Local Core Version: $current | Newest Core Version: $newest")
|
||||
if (current != newest) {
|
||||
MiraiConsole.logger("Updating from V$current -> V$newest, this is a force update")
|
||||
println("Updating Core/Lib from V$current -> V$newest, this is a force update")
|
||||
cleanCoreAndLib()
|
||||
runBlocking {
|
||||
downloadCoreAndLib(newest)
|
||||
}
|
||||
MiraiConsole.logger("Download complete")
|
||||
downloadCoreAndLib(newest)
|
||||
println("Download Core/Lib complete")
|
||||
}
|
||||
MiraiConsole.logger("Loading Core")
|
||||
loadCoreAndLib()
|
||||
MiraiConsole.logger("Mirai Core Loaded, current core version $newest")
|
||||
return newest
|
||||
}
|
||||
|
||||
fun loadCore(){
|
||||
println("Loading Core")
|
||||
loadCoreAndLib()
|
||||
println("Mirai Core and Libraries Loaded")
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断最新版本
|
||||
@ -86,14 +68,14 @@ object MiraiCoreLoader {
|
||||
private suspend fun getNewestVersion(): String {
|
||||
try {
|
||||
return """>([0-9])*\.([0-9])*\.([0-9])*/""".toRegex().findAll(
|
||||
Http.get<String> {
|
||||
url {
|
||||
protocol = URLProtocol.HTTPS
|
||||
host = "jcenter.bintray.com"
|
||||
path("net/mamoe/mirai-core-qqandroid-jvm/")
|
||||
}
|
||||
Http.get<String> {
|
||||
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 ->
|
||||
@ -101,9 +83,9 @@ object MiraiCoreLoader {
|
||||
}
|
||||
}!!
|
||||
} catch (e: Exception) {
|
||||
MiraiConsole.logger("Failed to fetch newest Core version, please seek for help")
|
||||
println("Failed to fetch newest Core version, please seek for help")
|
||||
e.printStackTrace()
|
||||
MiraiConsole.logger("Failed to fetch newest Core version, please seek for help")
|
||||
println("Failed to fetch newest Core version, please seek for help")
|
||||
exitProcess(1)
|
||||
}
|
||||
}
|
||||
@ -124,11 +106,8 @@ object MiraiCoreLoader {
|
||||
|
||||
|
||||
private fun cleanCoreAndLib() {
|
||||
this.coresPath.listFiles()?.forEach {
|
||||
if (it != null && it.extension == "jar") {
|
||||
it.delete()
|
||||
}
|
||||
}
|
||||
this.getCore()?.delete()
|
||||
this.getProtocolLib()?.delete()
|
||||
}
|
||||
|
||||
|
||||
@ -146,61 +125,52 @@ object MiraiCoreLoader {
|
||||
}
|
||||
|
||||
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<HttpResponse>(url.replace("{version}", version)).content
|
||||
}
|
||||
|
||||
var stream = kotlin.runCatching {
|
||||
MiraiConsole.logger("Downloading newest Protocol lib from Aliyun")
|
||||
downloadRequest(Links.libAliyun, version)
|
||||
}.getOrElse {
|
||||
kotlin.runCatching {
|
||||
MiraiConsole.logger("Downloading newest Protocol lib from JCenter")
|
||||
downloadRequest(Links.libJcenter, version)
|
||||
}.getOrElse { e ->
|
||||
MiraiConsole.logger("Failed to download Protocol lib, please seeking for help")
|
||||
e.printStackTrace()
|
||||
MiraiConsole.logger("Failed to download Protocol lib, please seeking for help")
|
||||
exitProcess(1)
|
||||
coroutineScope {
|
||||
launch {
|
||||
tryNTimesOrQuit(3) {
|
||||
kotlin.runCatching {
|
||||
println("Downloading newest Protocol lib from Aliyun")
|
||||
downloadRequest(Links.libAliyun, version)
|
||||
}.getOrElse {
|
||||
println("Downloading newest Protocol lib from JCenter")
|
||||
downloadRequest(Links.libJcenter, version)
|
||||
}.saveTo("mirai-core-qqandroid-jvm-$version.jar")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
stream.copyTo(fileStream)
|
||||
fileStream.flush()
|
||||
}
|
||||
launch {
|
||||
tryNTimesOrQuit(3) {
|
||||
val fileStream = File(contentPath.absolutePath + "/" + "mirai-core-jvm-$version.jar").also {
|
||||
withContext(Dispatchers.IO) {
|
||||
it.createNewFile()
|
||||
}
|
||||
}.outputStream()
|
||||
|
||||
fileStream = File(coresPath.absolutePath + "/" + "mirai-core-jvm-$version.jar").also {
|
||||
withContext(Dispatchers.IO) {
|
||||
it.createNewFile()
|
||||
val stream = try {
|
||||
println("Downloading newest Mirai Core from Aliyun")
|
||||
downloadRequest(Links.coreAliyun, version)
|
||||
} catch (ignored: Exception) {
|
||||
try {
|
||||
println("Downloading newest Mirai Core from JCenter")
|
||||
downloadRequest(Links.coreJcenter, version)
|
||||
} catch (e: Exception) {
|
||||
println("Failed to download Mirai Core, please seeking for help")
|
||||
e.printStackTrace()
|
||||
println("Failed to download Mirai Core, please seeking for help")
|
||||
exitProcess(1)
|
||||
}
|
||||
}
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
stream.copyTo(fileStream)
|
||||
fileStream.flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
}.outputStream()
|
||||
|
||||
|
||||
stream = try {
|
||||
MiraiConsole.logger("Downloading newest Mirai Core from Aliyun")
|
||||
downloadRequest(Links.coreAliyun, version)
|
||||
} catch (ignored: Exception) {
|
||||
try {
|
||||
MiraiConsole.logger("Downloading newest Mirai Core from JCenter")
|
||||
downloadRequest(Links.coreJcenter, 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")
|
||||
exitProcess(1)
|
||||
}
|
||||
}
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
stream.copyTo(fileStream)
|
||||
fileStream.flush()
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,8 +181,8 @@ object MiraiCoreLoader {
|
||||
val coreFile = getCore()!!
|
||||
val protocolFile = getProtocolLib()!!
|
||||
|
||||
MiraiConsole.logger("Core: $coreFile")
|
||||
MiraiConsole.logger("Protocol: $protocolFile")
|
||||
println("Core: $coreFile")
|
||||
println("Protocol: $protocolFile")
|
||||
|
||||
|
||||
val classloader = URLClassLoader(
|
||||
@ -231,15 +201,12 @@ object MiraiCoreLoader {
|
||||
println(Class.forName("net.mamoe.mirai.qqandroid.QQAndroid"))
|
||||
|
||||
} catch (e: ClassNotFoundException) {
|
||||
MiraiConsole.logger("Failed to load core, please seek for help")
|
||||
println("Failed to load core, please seek for help")
|
||||
e.printStackTrace()
|
||||
MiraiConsole.logger("Failed to load core, please seek for help")
|
||||
println("Failed to load core, please seek for help")
|
||||
exitProcess(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
package net.mamoe.mirai.console.wrapper
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.cio.CIO
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.utils.io.ByteReadChannel
|
||||
import io.ktor.utils.io.jvm.javaio.copyTo
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
val Http: HttpClient
|
||||
get() = HttpClient(CIO)
|
||||
|
||||
|
||||
inline fun <R> tryNTimesOrQuit(repeat: Int, block: (Int) -> R){
|
||||
var lastException: Throwable? = null
|
||||
|
||||
repeat(repeat) {
|
||||
try {
|
||||
block(it)
|
||||
return
|
||||
} catch (e: Throwable) {
|
||||
if (lastException == null) {
|
||||
lastException = e
|
||||
} else lastException!!.addSuppressed(e)
|
||||
}
|
||||
}
|
||||
|
||||
lastException!!.printStackTrace()
|
||||
exitProcess(1)
|
||||
}
|
||||
|
||||
|
||||
suspend inline fun HttpClient.downloadRequest(url: String, version: String): ByteReadChannel {
|
||||
return this.get<HttpResponse>(url.replace("{version}", version)).content
|
||||
}
|
||||
|
||||
/**
|
||||
* 只要填content path后面的就可以
|
||||
*/
|
||||
suspend fun ByteReadChannel.saveTo(filepath:String){
|
||||
val fileStream = File(contentPath.absolutePath + "/" + filepath).also {
|
||||
withContext(Dispatchers.IO) {
|
||||
it.createNewFile()
|
||||
}
|
||||
}.outputStream()
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
this@saveTo.copyTo(fileStream)
|
||||
fileStream.flush()
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
package net.mamoe.mirai.console.wrapper
|
||||
|
||||
import java.io.File
|
||||
|
||||
object LibManager{
|
||||
|
||||
val libPath by lazy{
|
||||
File(contentPath.absolutePath + "/lib/").also {
|
||||
if(!it.exists()){
|
||||
it.mkdirs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun clearLibs(){
|
||||
libPath.listFiles()?.forEach {
|
||||
it.delete()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 增加dependency 不是立刻下载
|
||||
* 全部完成后使用 @link downloadIfNeeded()开始下载
|
||||
*/
|
||||
|
||||
/**
|
||||
* 由Pom content提供必要依赖
|
||||
* LibManager会检查所有dependency的dependency
|
||||
*/
|
||||
fun addDependencyByPom(pomContent:String){
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 普通的增加一个dependency
|
||||
*/
|
||||
fun addDependency(){
|
||||
|
||||
}
|
||||
|
||||
suspend fun downloadIfNeeded(){
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -6,11 +6,54 @@
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
package net.mamoe.mirai.console.wrapper
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.cio.CIO
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.utils.io.ByteReadChannel
|
||||
import io.ktor.utils.io.jvm.javaio.copyTo
|
||||
import kotlinx.coroutines.*
|
||||
import java.io.File
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
|
||||
val contentPath by lazy {
|
||||
File(System.getProperty("user.dir") + "/content/").also {
|
||||
if (!it.exists()) {
|
||||
it.mkdirs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object WrapperMain {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
println("You are running Mirai-Console-Wrapper under " + System.getProperty("user.dir"))
|
||||
println("Starting version check...")
|
||||
/**
|
||||
* ask for type
|
||||
*/
|
||||
val type = CONSOLE_PURE
|
||||
|
||||
runBlocking {
|
||||
launch {
|
||||
CoreUpdator.versionCheck()
|
||||
}
|
||||
launch {
|
||||
ConsoleUpdator.versionCheck(type)
|
||||
}
|
||||
}
|
||||
println("Version check complete, starting Mirai")
|
||||
}
|
||||
}
|
||||
|
||||
class MiraiClassLoader(
|
||||
val core:File,
|
||||
val protocol: File,
|
||||
val console: File
|
||||
){
|
||||
|
||||
}
|
@ -17,7 +17,6 @@ import net.mamoe.mirai.console.command.CommandManager
|
||||
import net.mamoe.mirai.console.command.CommandSender
|
||||
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
||||
import net.mamoe.mirai.console.command.DefaultCommands
|
||||
import net.mamoe.mirai.console.core.MiraiCoreLoader
|
||||
import net.mamoe.mirai.console.plugins.PluginManager
|
||||
import net.mamoe.mirai.console.utils.MiraiConsoleUI
|
||||
import net.mamoe.mirai.utils.cryptor.ECDH
|
||||
@ -78,7 +77,6 @@ object MiraiConsole {
|
||||
logger("Mirai为开源项目,请自觉遵守开源项目协议")
|
||||
logger("Powered by Mamoe Technologies and contributors")
|
||||
|
||||
MiraiCoreLoader.loadCore()
|
||||
|
||||
/* 加载ECDH */
|
||||
try {
|
||||
|
@ -529,6 +529,7 @@ class TomlConfig internal constructor(content: String) : FileConfigImpl(content)
|
||||
Toml().read(content).toMap()
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
override fun serialize(config: ConfigSection): String {
|
||||
|
@ -0,0 +1,21 @@
|
||||
package net.mamoe.mirai.console.plugins
|
||||
|
||||
interface ConfigSectionTemplate{
|
||||
|
||||
|
||||
fun autoSave(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class MyConfigObject:ConfigSectionTemplate {
|
||||
|
||||
class MyTWClass : ConfigSectionTemplate {
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user