mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-27 00:30:17 +08:00
parent
36fc942ace
commit
c1090c1074
@ -152,6 +152,9 @@ public interface CommandManager {
|
|||||||
override suspend fun CommandSender.executeCommand(message: MessageChain): Command? =
|
override suspend fun CommandSender.executeCommand(message: MessageChain): Command? =
|
||||||
CommandManagerImpl.run { executeCommand(message) }
|
CommandManagerImpl.run { executeCommand(message) }
|
||||||
|
|
||||||
|
override val commandPrefix: String
|
||||||
|
get() = CommandManagerImpl.commandPrefix
|
||||||
|
|
||||||
override suspend fun Command.execute(
|
override suspend fun Command.execute(
|
||||||
sender: CommandSender,
|
sender: CommandSender,
|
||||||
args: MessageChain,
|
args: MessageChain,
|
||||||
|
@ -15,7 +15,7 @@ import java.io.OutputStream
|
|||||||
private const val LN = 10.toByte()
|
private const val LN = 10.toByte()
|
||||||
|
|
||||||
internal class BufferedOutputStream @JvmOverloads constructor(
|
internal class BufferedOutputStream @JvmOverloads constructor(
|
||||||
private val size: Int = 1024 * 1024 * 1024,
|
private val size: Int = 1024 * 1024,
|
||||||
private val logger: (String?) -> Unit
|
private val logger: (String?) -> Unit
|
||||||
) : ByteArrayOutputStream(size + 1) {
|
) : ByteArrayOutputStream(size + 1) {
|
||||||
override fun write(b: Int) {
|
override fun write(b: Int) {
|
||||||
|
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.console.pure
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
|
import net.mamoe.mirai.console.command.*
|
||||||
|
import net.mamoe.mirai.console.command.Command.Companion.primaryName
|
||||||
|
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommandDetailed
|
||||||
|
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
|
||||||
|
import net.mamoe.mirai.console.util.ConsoleInternalAPI
|
||||||
|
import net.mamoe.mirai.utils.DefaultLogger
|
||||||
|
import org.fusesource.jansi.Ansi
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
@ConsoleInternalAPI
|
||||||
|
internal fun startupConsoleThread() {
|
||||||
|
val service = Executors.newSingleThreadExecutor { code ->
|
||||||
|
thread(start = false, isDaemon = false, name = "Console Input", block = code::run)
|
||||||
|
}
|
||||||
|
val dispatch = service.asCoroutineDispatcher()
|
||||||
|
ConsoleUtils.miraiLineReader = { hint ->
|
||||||
|
withContext(dispatch) {
|
||||||
|
ConsoleUtils.lineReader.readLine(
|
||||||
|
if (hint.isNotEmpty()) {
|
||||||
|
ConsoleUtils.lineReader.printAbove(
|
||||||
|
Ansi.ansi()
|
||||||
|
.fgCyan().a(MiraiConsoleFrontEndPure.sdf.format(Date())).a(" ")
|
||||||
|
.fgMagenta().a(hint)
|
||||||
|
.reset()
|
||||||
|
.toString()
|
||||||
|
)
|
||||||
|
"$hint > "
|
||||||
|
} else "> "
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
object : AbstractCommand(ConsoleCommandOwner, "test") {
|
||||||
|
override val usage: String
|
||||||
|
get() = "? Why usage"
|
||||||
|
|
||||||
|
override suspend fun CommandSender.onCommand(args: Array<out Any>) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
launch { sendMessage("I1> " + MiraiConsole.frontEnd.requestInput("Value 1")) }
|
||||||
|
launch { sendMessage("I2> " + MiraiConsole.frontEnd.requestInput("Value 2")) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}.register(true)
|
||||||
|
*/
|
||||||
|
|
||||||
|
CoroutineScope(dispatch).launch {
|
||||||
|
val consoleLogger = DefaultLogger("Console")
|
||||||
|
while (isActive) {
|
||||||
|
try {
|
||||||
|
val next = MiraiConsoleFrontEndPure.requestInput("").let {
|
||||||
|
when {
|
||||||
|
it.startsWith(CommandManager.commandPrefix) -> {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
it == "?" -> CommandManager.commandPrefix + BuiltInCommands.Help.primaryName
|
||||||
|
else -> CommandManager.commandPrefix + it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next.isBlank()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
consoleLogger.debug("INPUT> $next")
|
||||||
|
val result = ConsoleCommandSenderImpl.executeCommandDetailed(next)
|
||||||
|
when (result.status) {
|
||||||
|
CommandExecuteStatus.SUCCESSFUL -> {
|
||||||
|
}
|
||||||
|
CommandExecuteStatus.EXECUTION_EXCEPTION -> {
|
||||||
|
result.exception?.printStackTrace()
|
||||||
|
}
|
||||||
|
CommandExecuteStatus.COMMAND_NOT_FOUND -> {
|
||||||
|
consoleLogger.warning("Unknown command: ${result.commandName}")
|
||||||
|
}
|
||||||
|
CommandExecuteStatus.PERMISSION_DENIED -> {
|
||||||
|
consoleLogger.warning("Permission denied.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: InterruptedException) {
|
||||||
|
return@launch
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
consoleLogger.error("Unhandled exception", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.let { consoleJob ->
|
||||||
|
MiraiConsole.job.invokeOnCompletion {
|
||||||
|
runCatching {
|
||||||
|
consoleJob.cancel()
|
||||||
|
}.exceptionOrNull()?.printStackTrace()
|
||||||
|
runCatching {
|
||||||
|
service.shutdownNow()
|
||||||
|
}.exceptionOrNull()?.printStackTrace()
|
||||||
|
runCatching {
|
||||||
|
ConsoleUtils.terminal.close()
|
||||||
|
}.exceptionOrNull()?.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@ internal object ConsoleUtils {
|
|||||||
|
|
||||||
val lineReader: LineReader
|
val lineReader: LineReader
|
||||||
val terminal: Terminal
|
val terminal: Terminal
|
||||||
|
lateinit var miraiLineReader: suspend (String) -> String
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ package net.mamoe.mirai.console.pure
|
|||||||
|
|
||||||
//import net.mamoe.mirai.console.command.CommandManager
|
//import net.mamoe.mirai.console.command.CommandManager
|
||||||
//import net.mamoe.mirai.console.utils.MiraiConsoleFrontEnd
|
//import net.mamoe.mirai.console.utils.MiraiConsoleFrontEnd
|
||||||
|
import io.ktor.utils.io.concurrent.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.Bot
|
||||||
@ -71,9 +72,15 @@ object MiraiConsoleFrontEndPure : MiraiConsoleFrontEnd {
|
|||||||
const val COLOR_RESET = "\u001b[39;49m"
|
const val COLOR_RESET = "\u001b[39;49m"
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private val sdf by lazy {
|
internal val sdf by ThreadLocal.withInitial {
|
||||||
|
// SimpleDateFormat not thread safe.
|
||||||
SimpleDateFormat("HH:mm:ss")
|
SimpleDateFormat("HH:mm:ss")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private operator fun <T> ThreadLocal<T>.getValue(thiz: Any, property: Any): T {
|
||||||
|
return this.get()
|
||||||
|
}
|
||||||
|
|
||||||
override val name: String
|
override val name: String
|
||||||
get() = "Pure"
|
get() = "Pure"
|
||||||
override val version: String
|
override val version: String
|
||||||
@ -90,28 +97,19 @@ object MiraiConsoleFrontEndPure : MiraiConsoleFrontEnd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun requestInput(hint: String): String {
|
override suspend fun requestInput(hint: String): String {
|
||||||
if (hint.isNotEmpty()) {
|
return ConsoleUtils.miraiLineReader(hint)
|
||||||
ConsoleUtils.lineReader.printAbove(
|
|
||||||
Ansi.ansi()
|
|
||||||
.fgCyan().a(sdf.format(Date()))
|
|
||||||
.fgMagenta().a(hint)
|
|
||||||
.toString()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return withContext(Dispatchers.IO) {
|
|
||||||
ConsoleUtils.lineReader.readLine("> ")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createLoginSolver(): LoginSolver {
|
override fun createLoginSolver(): LoginSolver {
|
||||||
return DefaultLoginSolver(
|
return DefaultLoginSolver(
|
||||||
input = suspend {
|
input = suspend {
|
||||||
requestInput("")
|
requestInput("LOGIN> ")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
class MiraiConsoleFrontEndPure : MiraiConsoleFrontEnd {
|
class MiraiConsoleFrontEndPure : MiraiConsoleFrontEnd {
|
||||||
private var requesting = false
|
private var requesting = false
|
||||||
|
@ -51,7 +51,7 @@ internal fun startup() {
|
|||||||
DefaultLogger = { MiraiConsoleFrontEndPure.loggerFor(it) }
|
DefaultLogger = { MiraiConsoleFrontEndPure.loggerFor(it) }
|
||||||
overrideSTD()
|
overrideSTD()
|
||||||
MiraiConsoleImplementationPure().start()
|
MiraiConsoleImplementationPure().start()
|
||||||
startConsoleThread()
|
startupConsoleThread()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun overrideSTD() {
|
internal fun overrideSTD() {
|
||||||
@ -71,56 +71,6 @@ internal fun overrideSTD() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun startConsoleThread() {
|
|
||||||
thread(name = "Console Input") {
|
|
||||||
val consoleLogger = DefaultLogger("Console")
|
|
||||||
try {
|
|
||||||
kotlinx.coroutines.runBlocking {
|
|
||||||
while (isActive) {
|
|
||||||
val next = MiraiConsoleFrontEndPure.requestInput("").let {
|
|
||||||
when {
|
|
||||||
it.startsWith(CommandManager.commandPrefix) -> {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
it == "?" -> CommandManager.commandPrefix + BuiltInCommands.Help.primaryName
|
|
||||||
else -> CommandManager.commandPrefix + it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (next.isBlank()) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
consoleLogger.debug("INPUT> $next")
|
|
||||||
val result = ConsoleCommandSenderImpl.executeCommandDetailed(next)
|
|
||||||
when (result.status) {
|
|
||||||
CommandExecuteStatus.SUCCESSFUL -> {
|
|
||||||
}
|
|
||||||
CommandExecuteStatus.EXECUTION_EXCEPTION -> {
|
|
||||||
result.exception?.printStackTrace()
|
|
||||||
}
|
|
||||||
CommandExecuteStatus.COMMAND_NOT_FOUND -> {
|
|
||||||
consoleLogger.warning("Unknown command: ${result.commandName}")
|
|
||||||
}
|
|
||||||
CommandExecuteStatus.PERMISSION_DENIED -> {
|
|
||||||
consoleLogger.warning("Permission denied.")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: InterruptedException) {
|
|
||||||
return@thread
|
|
||||||
}
|
|
||||||
}.let { thread ->
|
|
||||||
MiraiConsole.job.invokeOnCompletion {
|
|
||||||
runCatching {
|
|
||||||
thread.interrupt()
|
|
||||||
}.exceptionOrNull()?.printStackTrace()
|
|
||||||
runCatching {
|
|
||||||
ConsoleUtils.terminal.close()
|
|
||||||
}.exceptionOrNull()?.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object ConsoleCommandSenderImpl : ConsoleCommandSender() {
|
internal object ConsoleCommandSenderImpl : ConsoleCommandSender() {
|
||||||
override suspend fun sendMessage(message: Message) {
|
override suspend fun sendMessage(message: Message) {
|
||||||
|
Loading…
Reference in New Issue
Block a user