Mirai Console Front End Pure

This commit is contained in:
Karlatemp 2020-06-20 20:47:59 +08:00
parent 5e95348bae
commit b37f7bbb5f
No known key found for this signature in database
GPG Key ID: 21FBDDF664FF06F8
4 changed files with 217 additions and 61 deletions

View File

@ -0,0 +1,37 @@
/*
* 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.pure
import org.jline.reader.LineReader
import org.jline.reader.LineReaderBuilder
import org.jline.reader.impl.completer.NullCompleter
import org.jline.terminal.Terminal
import org.jline.terminal.TerminalBuilder
object ConsoleUtils {
val lineReader: LineReader
val terminal: Terminal
init {
val dumb = System.getProperty("java.class.path")
.contains("idea_rt.jar") || System.getProperty("mirai.idea") !== null
terminal = TerminalBuilder.builder()
.dumb(dumb)
.build()
lineReader = LineReaderBuilder.builder()
.terminal(terminal)
.completer(NullCompleter())
.build()
}
}

View File

@ -9,20 +9,86 @@
package net.mamoe.mirai.console.pure package net.mamoe.mirai.console.pure
import kotlinx.coroutines.delay //import net.mamoe.mirai.console.command.CommandManager
//import net.mamoe.mirai.console.utils.MiraiConsoleFrontEnd
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.MiraiConsoleFrontEnd
import net.mamoe.mirai.console.command.ConsoleCommandSender
import net.mamoe.mirai.console.utils.MiraiConsoleFrontEnd
import net.mamoe.mirai.utils.DefaultLogger import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.DefaultLoginSolver import net.mamoe.mirai.utils.DefaultLoginSolver
import net.mamoe.mirai.utils.LoginSolver import net.mamoe.mirai.utils.LoginSolver
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import org.fusesource.jansi.Ansi
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import kotlin.concurrent.thread import java.util.concurrent.ConcurrentHashMap
@Suppress("unused")
object MiraiConsoleFrontEndPure : MiraiConsoleFrontEnd {
private val globalLogger = DefaultLogger("Mirai")
private val cachedLoggers = ConcurrentHashMap<String, MiraiLogger>()
// companion object {
// ANSI color codes
const val COLOR_RED = "\u001b[38;5;196m"
const val COLOR_CYAN = "\u001b[38;5;87m"
const val COLOR_GREEN = "\u001b[38;5;82m"
// use a dark yellow(more like orange) instead of light one to save Solarized-light users
const val COLOR_YELLOW = "\u001b[38;5;220m"
const val COLOR_GREY = "\u001b[38;5;244m"
const val COLOR_BLUE = "\u001b[38;5;27m"
const val COLOR_NAVY = "\u001b[38;5;24m" // navy uniform blue
const val COLOR_PINK = "\u001b[38;5;207m"
const val COLOR_RESET = "\u001b[39;49m"
// }
val sdf by lazy {
SimpleDateFormat("HH:mm:ss")
}
override fun loggerFor(identity: String?): MiraiLogger {
identity?.apply {
return cachedLoggers.computeIfAbsent(this, DefaultLogger)
}
return globalLogger
}
override fun prePushBot(identity: Long) {
}
override fun pushBot(bot: Bot) {
}
override fun pushVersion(consoleVersion: String, consoleBuild: String, coreVersion: String) {
}
override suspend fun requestInput(hint: String): String {
if (hint.isNotEmpty()) {
ConsoleUtils.lineReader.printAbove(
Ansi.ansi()
.fgCyan().a(sdf.format(Date()))
.fgMagenta().a(hint)
.toString()
)
}
return ConsoleUtils.lineReader.readLine("> ")
}
override fun pushBotAdminStatus(identity: Long, admins: List<Long>) {
}
override fun createLoginSolver(): LoginSolver {
return DefaultLoginSolver(
input = suspend {
requestInput("")
}
)
}
}
/*
class MiraiConsoleFrontEndPure : MiraiConsoleFrontEnd { class MiraiConsoleFrontEndPure : MiraiConsoleFrontEnd {
private var requesting = false private var requesting = false
private var requestStr = "" private var requestStr = ""
@ -106,4 +172,4 @@ class MiraiConsoleFrontEndPure : MiraiConsoleFrontEnd {
} }
*/

View File

@ -0,0 +1,49 @@
/*
* 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
*
*/
@file:Suppress(
"INVISIBLE_MEMBER",
"INVISIBLE_REFERENCE",
"CANNOT_OVERRIDE_INVISIBLE_MEMBER",
"INVISIBLE_SETTER",
"INVISIBLE_GETTER",
"INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER",
"INVISIBLE_ABSTRACT_MEMBER_FROM_SUPE_WARNING"
)
package net.mamoe.mirai.console.pure
import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.console.IMiraiConsole
import net.mamoe.mirai.console.MiraiConsoleFrontEnd
import net.mamoe.mirai.console.plugin.PluginLoader
import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.MiraiLogger
import java.io.File
import java.util.*
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
private val delegateScope = CoroutineScope(EmptyCoroutineContext)
object MiraiConsolePure : IMiraiConsole {
override val build: String = "UNKNOWN"
override val builtInPluginLoaders: List<PluginLoader<*, *>> = LinkedList()
override val frontEnd: MiraiConsoleFrontEnd = MiraiConsoleFrontEndPure
override val mainLogger: MiraiLogger = DefaultLogger("Console")
override val rootDir: File = File("./test/console").also {
it.mkdirs()
}
override val version: String
get() = "UNKNOWN"
override val coroutineContext: CoroutineContext
get() = delegateScope.coroutineContext
}

View File

@ -7,68 +7,72 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:Suppress(
"INVISIBLE_MEMBER",
"INVISIBLE_REFERENCE",
"CANNOT_OVERRIDE_INVISIBLE_MEMBER",
"INVISIBLE_SETTER",
"INVISIBLE_GETTER",
"INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER",
"INVISIBLE_ABSTRACT_MEMBER_FROM_SUPE_WARNING"
)
package net.mamoe.mirai.console.pure package net.mamoe.mirai.console.pure
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsoleInitializer
import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.command.ConsoleCommandSender
import net.mamoe.mirai.console.command.DefaultCommands import net.mamoe.mirai.console.command.executeCommand
import net.mamoe.mirai.console.plugins.PluginManager import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.console.utils.MiraiConsoleFrontEnd import net.mamoe.mirai.message.data.PlainText
import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.PlatformLogger
import org.fusesource.jansi.Ansi
import kotlin.concurrent.thread import kotlin.concurrent.thread
class MiraiConsolePureLoader { object MiraiConsolePureLoader {
companion object {
@JvmStatic @JvmStatic
fun load( fun main(args: Array<String>?) {
coreVersion: String, startup()
consoleVersion: String }
) { }
start(
MiraiConsoleFrontEndPure(), private val ANSI_RESET = Ansi().reset().toString()
coreVersion,
consoleVersion internal fun overrideLoggingSystem() {
) DefaultLogger = {
Runtime.getRuntime().addShutdownHook(thread(start = false) { PlatformLogger(identity = it, output = { line ->
MiraiConsole.stop() ConsoleUtils.lineReader.printAbove(line + ANSI_RESET)
}) })
} }
}
internal fun startup() {
overrideLoggingSystem()
MiraiConsoleInitializer.init(MiraiConsolePure)
startConsoleThread()
}
internal fun startConsoleThread() {
thread(name = "Console", isDaemon = false) {
val consoleLogger = DefaultLogger("Console")
kotlinx.coroutines.runBlocking {
while (true) {
val next = MiraiConsoleFrontEndPure.requestInput("")
consoleLogger.debug("INPUT> $next")
kotlin.runCatching {
if (!ConsoleCS.executeCommand(PlainText(next))) { // No such command
consoleLogger.warning("Unknown command: " + next.split(' ')[0])
}
}.onFailure {
consoleLogger.error("Exception in executing command: $next", it)
}
}
}
} }
} }
/** object ConsoleCS : ConsoleCommandSender() {
* 启动 Console override suspend fun sendMessage(message: Message) {
*/ ConsoleUtils.lineReader.printAbove(message.contentToString())
@JvmOverloads
internal fun start(
frontEnd: MiraiConsoleFrontEnd,
coreVersion: String = "0.0.0",
consoleVersion: String = "0.0.0",
path: String = System.getProperty("user.dir")
) {
if (MiraiConsole.started) {
return
} }
MiraiConsole.started = true
this.path = path
/* 初始化前端 */
this.version = consoleVersion
this.frontEnd = frontEnd
this.frontEnd.pushVersion(consoleVersion, MiraiConsole.build, coreVersion)
logger("Mirai-console now running under $path")
logger("Get news in github: https://github.com/mamoe/mirai")
logger("Mirai为开源项目请自觉遵守开源项目协议")
logger("Powered by Mamoe Technologies and contributors")
/* 依次启用功能 */
DefaultCommands()
PluginManager.loadPlugins()
CommandManager.start()
/* 通知启动完成 */
logger("Mirai-console 启动完成")
logger("\"login qqnumber qqpassword \" to login a bot")
logger("\"login qq号 qq密码 \" 来登录一个BOT")
/* 尝试从系统配置自动登录 */
DefaultCommands.tryLoginAuto()
} }