Review: misc improvements

This commit is contained in:
Him188 2020-03-21 16:07:48 +08:00
parent 02173d96df
commit 20e699fb31
9 changed files with 104 additions and 126 deletions

View File

@ -11,7 +11,7 @@ const val CONSOLE_TERMINAL = "Terminal"
const val CONSOLE_GRAPHICAL = "Graphical"
object ConsoleUpdater {
internal object ConsoleUpdater {
@Suppress("SpellCheckingInspection")
private object Links : HashMap<String, Map<String, String>>() {

View File

@ -20,7 +20,7 @@ import java.net.URLClassLoader
import kotlin.math.pow
import kotlin.system.exitProcess
object CoreUpdator {
internal object CoreUpdater {
fun getProtocolLib(): File? {
contentPath.listFiles()?.forEach { file ->

View File

@ -1,9 +1,9 @@
@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.features.ClientRequestException
import io.ktor.client.request.get
import io.ktor.client.statement.HttpResponse
import io.ktor.utils.io.ByteReadChannel
@ -11,14 +11,11 @@ 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)
internal val Http: HttpClient = HttpClient(CIO)
inline fun <R> tryNTimesOrQuit(repeat: Int, errorHint: String, block: (Int) -> R){
internal inline fun <R> tryNTimesOrQuit(repeat: Int, errorHint: String, block: (Int) -> R) {
var lastException: Throwable? = null
repeat(repeat) {
@ -38,82 +35,84 @@ inline fun <R> tryNTimesOrQuit(repeat: Int, errorHint: String, block: (Int) -> R
}
suspend inline fun HttpClient.downloadRequest(url: String): ByteReadChannel {
return with(this.get<HttpResponse>(url)){
if(this.status.value == 404 || this.status.value == 403){
internal suspend inline fun HttpClient.downloadRequest(url: String): ByteReadChannel {
return with(this.get<HttpResponse>(url)) {
if (this.status.value == 404 || this.status.value == 403) {
error("File not found")
}
if(this.headers["status"] !=null && this.headers["status"] == "404"){
if (this.headers["status"] != null && this.headers["status"] == "404") {
error("File not found")
}
this.content
}
}
private val jcenterPath = "https://jcenter.bintray.com/{group}/{project}/{version}/:{project}-{version}.{extension}"
private val aliyunPath = "https://maven.aliyun.com/nexus/content/repositories/jcenter/{group}/{project}/{version}/{project}-{version}.{extension}"
private val jcenterPath = "https://jcenter.bintray.com/{group}/{project}/{version}/:{project}-{version}.{extension}"
private val aliyunPath =
"https://maven.aliyun.com/nexus/content/repositories/jcenter/{group}/{project}/{version}/{project}-{version}.{extension}"
private fun String.buildPath(
groupName: String,
projectName: String,
version: String,
extension: String
):String{
): String {
return this
.replace(
"{group}",groupName
"{group}", groupName
)
.replace(
"{project}",projectName
"{project}", projectName
)
.replace(
"{extension}",extension
"{extension}", extension
)
.replace(
"{version}",version
"{version}", version
)
}
suspend fun HttpClient.downloadMaven(
internal suspend fun HttpClient.downloadMaven(
groupName: String,
projectName: String,
version: String,
extension: String
):ByteReadChannel{
): ByteReadChannel {
return kotlin.runCatching {
downloadRequest(
aliyunPath.buildPath(groupName,projectName,version,extension)
aliyunPath.buildPath(groupName, projectName, version, extension)
)
}.getOrElse {
downloadRequest(
jcenterPath.buildPath(groupName,projectName,version,extension)
jcenterPath.buildPath(groupName, projectName, version, extension)
)
}
}
suspend inline fun HttpClient.downloadMavenArchive(
internal suspend inline fun HttpClient.downloadMavenArchive(
groupName: String,
projectName: String,
version: String
):ByteReadChannel{
return downloadMaven(groupName,projectName,version,"jar")
): ByteReadChannel {
return downloadMaven(groupName, projectName, version, "jar")
}
suspend inline fun HttpClient.downloadMavenPom(
internal suspend inline fun HttpClient.downloadMavenPom(
groupName: String,
projectName: String,
version: String
):ByteReadChannel{
return downloadMaven(groupName,projectName,version,"pom")
): ByteReadChannel {
return downloadMaven(groupName, projectName, version, "pom")
}
suspend fun HttpClient.downloadMavenPomAsString(
internal suspend fun HttpClient.downloadMavenPomAsString(
groupName: String,
projectName: String,
version: String
):String{
): String {
return kotlin.runCatching {
this.get<String>(
aliyunPath.buildPath(groupName,projectName,version,"pom")
aliyunPath.buildPath(groupName, projectName, version, "pom")
)
}.getOrElse {
this.get(
@ -123,12 +122,11 @@ suspend fun HttpClient.downloadMavenPomAsString(
}
/**
* 只要填content path后面的就可以
* 只要填 content path 后面的就可以
*/
suspend fun ByteReadChannel.saveToContent(filepath:String){
val fileStream = File(contentPath.absolutePath + "/" + filepath).also {
internal suspend fun ByteReadChannel.saveToContent(filepath: String) {
val fileStream = File(contentPath.absolutePath + "/" + filepath).also {
withContext(Dispatchers.IO) {
it.createNewFile()
}

View File

@ -9,7 +9,10 @@
@file:Suppress("EXPERIMENTAL_API_USAGE")
package net.mamoe.mirai.console.wrapper
import kotlinx.coroutines.*
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.File
import java.net.URLClassLoader
import java.util.*
@ -56,31 +59,31 @@ object WrapperMain {
println("Starting version check...")
runBlocking {
launch {
CoreUpdator.versionCheck()
CoreUpdater.versionCheck()
}
launch {
ConsoleUpdater.versionCheck(type)
}
}
println("Version check complete, starting Mirai")
println("Core :" + CoreUpdator.getCore()!!)
println("Protocol:" + CoreUpdator.getProtocolLib()!!)
println("Console :" + ConsoleUpdater.getFile()!! )
println("Core :" + CoreUpdater.getCore()!!)
println("Protocol:" + CoreUpdater.getProtocolLib()!!)
println("Console :" + ConsoleUpdater.getFile()!!)
println("Root :" + System.getProperty("user.dir") + "/")
val loader = MiraiClassLoader(
CoreUpdator.getCore()!!,
CoreUpdator.getProtocolLib()!!,
CoreUpdater.getCore()!!,
CoreUpdater.getProtocolLib()!!,
ConsoleUpdater.getFile()!!,
this.javaClass.classLoader
)
when(type) {
when (type) {
CONSOLE_PURE -> {
loader.loadClass("net.mamoe.mirai.BotFactoryJvm")
loader.loadClass(
"net.mamoe.mirai.console.pure.MiraiConsolePureLoader"
).getMethod("load", String::class.java,String::class.java)
.invoke(null,CoreUpdator.getCurrentVersion(),ConsoleUpdater.getCurrentVersion())
"net.mamoe.mirai.console.pure.MiraiConsolePureLoader"
).getMethod("load", String::class.java, String::class.java)
.invoke(null, CoreUpdater.getCurrentVersion(), ConsoleUpdater.getCurrentVersion())
}
}
}

View File

@ -17,6 +17,8 @@ import net.mamoe.mirai.message.data.Message
/**
* 指令发送者
*
* @see AbstractCommandSender 请继承于该抽象类
*/
interface CommandSender {
/**
@ -35,7 +37,7 @@ interface CommandSender {
fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) }
}
abstract class CommandSenderImpl : CommandSender {
abstract class AbstractCommandSender : CommandSender {
internal val builder = StringBuilder()
override fun appendMessage(message: String) {
@ -52,7 +54,7 @@ abstract class CommandSenderImpl : CommandSender {
/**
* 控制台指令执行者. 代表由控制台执行指令
*/
object ConsoleCommandSender : CommandSenderImpl() {
object ConsoleCommandSender : AbstractCommandSender() {
override suspend fun sendMessage(messageChain: Message) {
MiraiConsole.logger("[Command]", 0, messageChain.toString())
}
@ -71,7 +73,7 @@ object ConsoleCommandSender : CommandSenderImpl() {
* 联系人指令执行者. 代表由一个 QQ 用户执行指令
*/
@Suppress("MemberVisibilityCanBePrivate")
open class ContactCommandSender(val contact: Contact) : CommandSenderImpl() {
open class ContactCommandSender(val contact: Contact) : AbstractCommandSender() {
override suspend fun sendMessage(messageChain: Message) {
contact.sendMessage(messageChain)
}

View File

@ -23,7 +23,9 @@ import java.net.URLClassLoader
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/**
* 所有插件的基类
*/
abstract class PluginBase
@JvmOverloads constructor(coroutineContext: CoroutineContext = EmptyCoroutineContext) : CoroutineScope {
@ -34,7 +36,7 @@ abstract class PluginBase
* 插件被分配的数据目录数据目录会与插件名称同名
*/
val dataFolder: File by lazy {
File(PluginManager.pluginsPath + "/" + PluginManager.lastPluginName).also {
File(PluginManager.pluginsPath + "/" + pluginName).also {
it.mkdir()
}
}
@ -69,31 +71,13 @@ abstract class PluginBase
}
internal fun enable() {
this.onEnable()
}
/**
* 加载一个data folder中的Config
* 这个config是read-write的
* 加载一个 [dataFolder] 中的 [Config]
*/
fun loadConfig(fileName: String): Config {
return Config.load(dataFolder.absolutePath + "/" + fileName)
}
@JvmOverloads
internal fun disable(throwable: CancellationException? = null) {
this.coroutineContext[Job]!!.cancelChildren(throwable)
try {
this.onDisable()
} catch (e: Exception) {
logger.info(e)
}
}
internal var pluginName: String = ""
val logger: MiraiLogger by lazy {
SimpleLogger("Plugin $pluginName") { priority, message, e ->
val identityString = "[${pluginName}]"
@ -120,16 +104,34 @@ abstract class PluginBase
/**
* 加载 resource 中的 [Config]
* 这个 [Config] read-only
* 这个 [Config] 只读
*/
fun getResourcesConfig(fileName: String): Config {
if (!fileName.contains(".")) {
error("Unknown Config Type")
}
require(fileName.contains(".")) { "Unknown Config Type" }
return Config.load(getResources(fileName) ?: error("No such file: $fileName"), fileName.substringAfter('.'))
}
// internal
internal fun enable() {
this.onEnable()
}
internal fun disable(throwable: CancellationException? = null) {
this.coroutineContext[Job]!!.cancelChildren(throwable)
try {
this.onDisable()
} catch (e: Exception) {
logger.info(e)
}
}
internal var pluginName: String = ""
}
/**
* 插件描述
*/
class PluginDescription(
val name: String,
val author: String,

View File

@ -66,8 +66,7 @@ class MiraiConsoleUIPure : MiraiConsoleUI {
override fun pushLog(priority: LogPriority, identityStr: String, identity: Long, message: String) {
var priorityStr = "[${priority.name}]"
val _message = message + COLOR_RESET
/**
/*
* 通过ANSI控制码添加颜色
* 更多的颜色定义在 [MiraiConsoleUIPure] companion
*/
@ -86,7 +85,7 @@ class MiraiConsoleUIPure : MiraiConsoleUI {
else -> priorityStr
}
println("\u001b[0m " + sdf.format(Date()) + " $priorityStr $identityStr $_message")
println("\u001b[0m " + sdf.format(Date()) + " $priorityStr $identityStr ${message + COLOR_RESET}")
}
override fun prePushBot(identity: Long) {

View File

@ -2,25 +2,25 @@ package net.mamoe.mirai.console.scheduler
import net.mamoe.mirai.console.plugins.PluginBase
interface SchedulerTask<T:PluginBase>{
abstract fun onTick(i:Long)
interface SchedulerTask<T : PluginBase> {
abstract fun onTick(i: Long)
abstract fun onRun()
}
abstract class RepeatTask<T:PluginBase>(
abstract class RepeatTask<T : PluginBase>(
val intervalInMs: Int
):SchedulerTask<T>{
) : SchedulerTask<T> {
override fun onTick(i: Long) {
if(i%intervalInMs == 0L){
if (i % intervalInMs == 0L) {
onRun()
}
}
companion object{
fun <T:PluginBase> of(
companion object {
fun <T : PluginBase> of(
intervalInMs: Int, runnable: () -> Unit
):RepeatTask<T>{
): RepeatTask<T> {
return AnonymousRepeatTask<T>(
intervalInMs, runnable
)
@ -28,42 +28,18 @@ abstract class RepeatTask<T:PluginBase>(
}
}
internal class AnonymousRepeatTask<T: PluginBase>(
internal class AnonymousRepeatTask<T : PluginBase>(
intervalInMs: Int, private val runnable: () -> Unit
): RepeatTask<T>(intervalInMs){
) : RepeatTask<T>(intervalInMs) {
override fun onRun() {
runnable.invoke()
}
}
fun <T:PluginBase> T.repeatTask(
fun <T : PluginBase> T.repeatTask(
intervalInMs: Int, runnable: () -> Unit
):RepeatTask<T>{
): RepeatTask<T> {
return AnonymousRepeatTask<T>(
intervalInMs, runnable
)
}
fun <T> repeatTask(){
}
class X: PluginBase() {
override fun onLoad() {
//kotlin
this.repeatTask(5){
}
//java1
RepeatTask.of<X>(5){
}
//java2
class Xtask:RepeatTask<X>(5){
override fun onRun() {
}
}
}
}

View File

@ -14,15 +14,14 @@ import net.mamoe.mirai.utils.LoginSolver
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
/**
* 只需要实现一个这个 传入MiraiConsole 就可以绑定UI层与Console层
* 注意线程
* 只需要实现一个这个传入 MiraiConsole 就可以绑定 UI 层与 Console
* 需要保证线程安全
*/
interface MiraiConsoleUI {
/**
* UI层展示一条log
* UI 层展示一条 log
*
* identitylog所属的screen, Main=0; Bot=Bot.uin
* identitylog 所属的 screen, Main=0; Bot=Bot.uin
*/
fun pushLog(
identity: Long,
@ -37,14 +36,14 @@ interface MiraiConsoleUI {
)
/**
* UI层准备接受新增的一个BOT
* UI 层准备接受新增的一个BOT
*/
fun prePushBot(
identity: Long
)
/**
* UI层接受一个新的bot
* UI 层接受一个新的bot
* */
fun pushBot(
bot: Bot
@ -58,14 +57,13 @@ interface MiraiConsoleUI {
)
/**
* 让UI层提供一个Input
* 这个Input 等于 Command
* UI 层提供一个输入, 相当于 [readLine]
*/
suspend fun requestInput(hint:String): String
suspend fun requestInput(hint: String): String
/**
* UI层更新BOT管理员的数据
* UI 层更新 bot 管理员的数据
*/
fun pushBotAdminStatus(
identity: Long,
@ -73,7 +71,7 @@ interface MiraiConsoleUI {
)
/**
* UI层创建一个LoginSolver
* UI 层创建一个 [LoginSolver]
*/
fun createLoginSolver(): LoginSolver