mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-04 09:12:24 +08:00
Terminal (#179)
* Rename ConsolePure to ConsoleTerminal * Fix the way to close console with Ctrl+C * Fix windows pipeline error. Fix EndOfFileException * Add ConsoleExperimentalApi * Collect imports * Review - Change old CLI main deprecation level to ERROR - Update documents - Update tasks from pure to terminal * Fix error in closing console. * Fix terminal closing and Ctrl+C closing. * Add console shut-downing status * Don't invokeOnCompletion when console shut-downing * Fix Input interrupt * Ensure active unless console is shut downing * Change MiraiConsole.isShutDowning to `!job.isActive` * Code Review - Update Message on MiraiConsolePureLoader.kt - Change MiraiConsole.isShutDowning to MiraiConsole.isActive - Change MiraiConsole.shutdown to ConsoleInternalApi * run catching * Fix console input * Update shutdown * Fix module * Revert 5199395 * Typo
This commit is contained in:
parent
f990b7ce8c
commit
8fe2506e75
4
.github/workflows/bintray.yml
vendored
4
.github/workflows/bintray.yml
vendored
@ -32,6 +32,6 @@ jobs:
|
|||||||
run: ./gradlew :mirai-console:fillBuildConstants -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }} -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
run: ./gradlew :mirai-console:fillBuildConstants -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }} -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||||
- name: Gradle :mirai-console:bintrayUpload
|
- name: Gradle :mirai-console:bintrayUpload
|
||||||
run: ./gradlew :mirai-console:bintrayUpload -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }} -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
run: ./gradlew :mirai-console:bintrayUpload -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }} -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||||
- name: Gradle :mirai-console-pure:bintrayUpload
|
- name: Gradle :mirai-console-terminal:bintrayUpload
|
||||||
run: ./gradlew :mirai-console-pure:bintrayUpload -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }} -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
run: ./gradlew :mirai-console-terminal:bintrayUpload -Dbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_user=${{ secrets.BINTRAY_USER }} -Dbintray_key=${{ secrets.BINTRAY_KEY }} -Pbintray_key=${{ secrets.BINTRAY_KEY }}
|
||||||
|
|
||||||
|
4
.github/workflows/shadow.yml
vendored
4
.github/workflows/shadow.yml
vendored
@ -28,8 +28,8 @@ jobs:
|
|||||||
run: ./gradlew build # if test's failed, don't publish
|
run: ./gradlew build # if test's failed, don't publish
|
||||||
- name: Gradle :mirai-console:githubUpload
|
- name: Gradle :mirai-console:githubUpload
|
||||||
run: ./gradlew :mirai-console:githubUpload -Dgithub_token=${{ secrets.MAMOE_TOKEN }} -Pgithub_token=${{ secrets.MAMOE_TOKEN }}
|
run: ./gradlew :mirai-console:githubUpload -Dgithub_token=${{ secrets.MAMOE_TOKEN }} -Pgithub_token=${{ secrets.MAMOE_TOKEN }}
|
||||||
- name: Gradle :mirai-console-pure:githubUpload
|
- name: Gradle :mirai-console-terminal:githubUpload
|
||||||
run: ./gradlew :mirai-console-pure:githubUpload -Dgithub_token=${{ secrets.MAMOE_TOKEN }} -Pgithub_token=${{ secrets.MAMOE_TOKEN }}
|
run: ./gradlew :mirai-console-terminal:githubUpload -Dgithub_token=${{ secrets.MAMOE_TOKEN }} -Pgithub_token=${{ secrets.MAMOE_TOKEN }}
|
||||||
|
|
||||||
|
|
||||||
# - name: Upload artifact
|
# - name: Upload artifact
|
||||||
|
@ -28,12 +28,11 @@ console 由后端和前端一起工作. 使用时必须选择一个前端.
|
|||||||
|
|
||||||
前端:
|
前端:
|
||||||
|
|
||||||
- `mirai-console-pure`: console 的轻量命令行前端.
|
- `mirai-console-terminal`: console 的 Unix 终端界面前端.
|
||||||
- `mirai-console-graphical`: console 的 JavaFX 图形化界面前端. (开发中)
|
- `mirai-console-graphical`: console 的 JavaFX 图形化界面前端. (开发中)
|
||||||
- `mirai-console-terminal`: console 的 Unix 终端界面前端. (开发中)
|
|
||||||
|
|
||||||
|
|
||||||
**注意:`mirai-console` 后端和 pure 前端正在进行完全的重构, 所有 API 都不具有稳定性**
|
**注意:`mirai-console` 后端和 terminal 前端正在进行完全的重构, 所有 API 都不具有稳定性**
|
||||||
|
|
||||||
### 使用
|
### 使用
|
||||||
|
|
||||||
@ -56,7 +55,7 @@ dependencies {
|
|||||||
implementation("net.mamoe:mirai-core:$CORE_VERSION") // mirai-core 的 API
|
implementation("net.mamoe:mirai-core:$CORE_VERSION") // mirai-core 的 API
|
||||||
implementation("net.mamoe:mirai-console:$CONSOLE_VERSION") // 后端
|
implementation("net.mamoe:mirai-console:$CONSOLE_VERSION") // 后端
|
||||||
|
|
||||||
testImplementation("net.mamoe:mirai-console-pure:$CONSOLE_VERSION") // 前端, 用于启动测试
|
testImplementation("net.mamoe:mirai-console-terminal:$CONSOLE_VERSION") // 前端, 用于启动测试
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import kotlinx.coroutines.Job
|
|||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.Bot
|
||||||
import net.mamoe.mirai.console.MiraiConsole.INSTANCE
|
import net.mamoe.mirai.console.MiraiConsole.INSTANCE
|
||||||
import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
|
import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
|
||||||
|
import net.mamoe.mirai.console.command.BuiltInCommands
|
||||||
import net.mamoe.mirai.console.extensions.BotConfigurationAlterer
|
import net.mamoe.mirai.console.extensions.BotConfigurationAlterer
|
||||||
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
||||||
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
|
||||||
@ -146,6 +147,10 @@ public interface MiraiConsole : CoroutineScope {
|
|||||||
else -> null!!
|
else -> null!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConsoleExperimentalApi("This is a low-level API and might be removed in the future.")
|
||||||
|
public val isActive: Boolean
|
||||||
|
get() = job.isActive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,8 @@ internal object BuiltInJvmPluginLoaderImpl :
|
|||||||
|
|
||||||
override fun disable(plugin: JvmPlugin) {
|
override fun disable(plugin: JvmPlugin) {
|
||||||
if (!plugin.isEnabled) return
|
if (!plugin.isEnabled) return
|
||||||
|
|
||||||
|
if (MiraiConsole.isActive)
|
||||||
ensureActive()
|
ensureActive()
|
||||||
|
|
||||||
if (plugin is JvmPluginInternal) {
|
if (plugin is JvmPluginInternal) {
|
||||||
|
@ -151,6 +151,7 @@ internal abstract class JvmPluginInternal(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.also {
|
.also {
|
||||||
|
if (!MiraiConsole.isActive) return@also
|
||||||
BuiltInJvmPluginLoaderImpl.coroutineContext[Job]!!.invokeOnCompletion {
|
BuiltInJvmPluginLoaderImpl.coroutineContext[Job]!!.invokeOnCompletion {
|
||||||
this.cancel()
|
this.cancel()
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,7 @@ object Versions {
|
|||||||
const val core = "1.3.0"
|
const val core = "1.3.0"
|
||||||
const val console = "1.0-RC-dev-2"
|
const val console = "1.0-RC-dev-2"
|
||||||
const val consoleGraphical = "0.0.7"
|
const val consoleGraphical = "0.0.7"
|
||||||
const val consoleTerminal = "0.1.0"
|
const val consoleTerminal = console
|
||||||
const val consolePure = console
|
|
||||||
|
|
||||||
const val kotlinCompiler = "1.4.10"
|
const val kotlinCompiler = "1.4.10"
|
||||||
const val kotlinStdlib = kotlinCompiler
|
const val kotlinStdlib = kotlinCompiler
|
||||||
|
16
docs/Run.md
16
docs/Run.md
@ -19,16 +19,16 @@ https://github.com/LXY1226/MiraiOK
|
|||||||
- mirai-console 任一前端
|
- mirai-console 任一前端
|
||||||
- 相关依赖
|
- 相关依赖
|
||||||
|
|
||||||
只有 mirai-console 前端才有入口点 `main` 方法。目前只有一个 pure 前端可用。
|
只有 mirai-console 前端才有入口点 `main` 方法。目前只有一个 terminal 前端可用。
|
||||||
|
|
||||||
### 启动 mirai-console-pure 前端
|
### 启动 mirai-console-terminal 前端
|
||||||
|
|
||||||
mirai 在版本发布时会同时发布打包依赖的 Shadow JAR,存放在 [mirai-repo]。
|
mirai 在版本发布时会同时发布打包依赖的 Shadow JAR,存放在 [mirai-repo]。
|
||||||
|
|
||||||
1. 在 [mirai-repo] 下载如下三个模块的最新版本文件并放到一个文件夹内 (如 `libs`):
|
1. 在 [mirai-repo] 下载如下三个模块的最新版本文件并放到一个文件夹内 (如 `libs`):
|
||||||
- mirai-core-qqandroid
|
- mirai-core-qqandroid
|
||||||
- mirai-console
|
- mirai-console
|
||||||
- mirai-console-pure
|
- mirai-console-terminal
|
||||||
|
|
||||||
2. 创建一个新的文件, 名为 `start-mirai-console.bat`/`start-mirai-console.ps1`/`start-mirai-console.sh`
|
2. 创建一个新的文件, 名为 `start-mirai-console.bat`/`start-mirai-console.ps1`/`start-mirai-console.sh`
|
||||||
|
|
||||||
@ -36,26 +36,26 @@ Windows CMD:
|
|||||||
```shell script
|
```shell script
|
||||||
@echo off
|
@echo off
|
||||||
title Mirai Console
|
title Mirai Console
|
||||||
java -cp "./libs/*" net.mamoe.mirai.console.pure.MiraiConsolePureLoader %*
|
java -cp "./libs/*" net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader %*
|
||||||
pause
|
pause
|
||||||
```
|
```
|
||||||
|
|
||||||
Windows PowerShell:
|
Windows PowerShell:
|
||||||
```shell script
|
```shell script
|
||||||
$Host.UI.RawUI.WindowTitle = "Mirai Console"
|
$Host.UI.RawUI.WindowTitle = "Mirai Console"
|
||||||
java -cp "./libs/*" net.mamoe.mirai.console.pure.MiraiConsolePureLoader $args
|
java -cp "./libs/*" net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader $args
|
||||||
pause
|
pause
|
||||||
```
|
```
|
||||||
|
|
||||||
Linux:
|
Linux:
|
||||||
```shell script
|
```shell script
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
java -cp "./libs/*" net.mamoe.mirai.console.pure.MiraiConsolePureLoader $*
|
java -cp "./libs/*" net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader $*
|
||||||
```
|
```
|
||||||
|
|
||||||
然后就可以开始使用 mirai-console 了
|
然后就可以开始使用 mirai-console 了
|
||||||
|
|
||||||
### mirai-console-pure 前端参数
|
### mirai-console-terminal 前端参数
|
||||||
使用 `./start-mirai-console --help` 查看 mirai-console-pure 支持的启动参数
|
使用 `./start-mirai-console --help` 查看 mirai-console-terminal 支持的启动参数
|
||||||
|
|
||||||
[mirai-repo]: https://github.com/project-mirai/mirai-repo/tree/master/shadow
|
[mirai-repo]: https://github.com/project-mirai/mirai-repo/tree/master/shadow
|
||||||
|
@ -66,10 +66,10 @@ ext.apply {
|
|||||||
this.set("shadowJar", x)
|
this.set("shadowJar", x)
|
||||||
}
|
}
|
||||||
|
|
||||||
version = Versions.consolePure
|
version = Versions.consoleTerminal
|
||||||
|
|
||||||
description = "Console Pure CLI frontend for mirai"
|
description = "Console Terminal CLI frontend for mirai"
|
||||||
|
|
||||||
setupPublishing("mirai-console-pure", bintrayPkgName = "mirai-console-pure")
|
setupPublishing("mirai-console-terminal", bintrayPkgName = "mirai-console-terminal")
|
||||||
|
|
||||||
// endregion
|
// endregion
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.console.pure
|
||||||
|
|
||||||
|
import net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
message = "Please use MiraiConsoleTerminalLoader",
|
||||||
|
level = DeprecationLevel.ERROR,
|
||||||
|
replaceWith = ReplaceWith(
|
||||||
|
"MiraiConsoleTerminalLoader",
|
||||||
|
"net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
object MiraiConsolePureLoader {
|
||||||
|
@Deprecated(
|
||||||
|
message = "for binary compatibility",
|
||||||
|
level = DeprecationLevel.ERROR
|
||||||
|
)
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
System.err.println("WARNING: Mirai Console Pure已经更名为 Mirai Console Terminal")
|
||||||
|
System.err.println("请使用新的入口点 net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader")
|
||||||
|
MiraiConsoleTerminalLoader.main(args)
|
||||||
|
}
|
||||||
|
}
|
@ -5,9 +5,10 @@
|
|||||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||||
*
|
*
|
||||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.mamoe.mirai.console.pure
|
package net.mamoe.mirai.console.terminal
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.console.terminal
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CancellableContinuation
|
||||||
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
|
import net.mamoe.mirai.console.util.ConsoleInput
|
||||||
|
import org.fusesource.jansi.Ansi
|
||||||
|
import org.jline.reader.EndOfFileException
|
||||||
|
import java.time.Instant
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import kotlin.coroutines.resumeWithException
|
||||||
|
|
||||||
|
|
||||||
|
internal object ConsoleInputImpl : ConsoleInput {
|
||||||
|
private val format = DateTimeFormatter.ofPattern("HH:mm:ss")
|
||||||
|
internal val thread = Executors.newSingleThreadExecutor { task ->
|
||||||
|
Thread(task, "Mirai Console Input Thread").also {
|
||||||
|
it.isDaemon = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal var executingCoroutine: CancellableContinuation<String>? = null
|
||||||
|
|
||||||
|
|
||||||
|
override suspend fun requestInput(hint: String): String {
|
||||||
|
return suspendCancellableCoroutine { coroutine ->
|
||||||
|
if (thread.isShutdown || thread.isTerminated) {
|
||||||
|
coroutine.resumeWithException(EndOfFileException())
|
||||||
|
return@suspendCancellableCoroutine
|
||||||
|
}
|
||||||
|
executingCoroutine = coroutine
|
||||||
|
kotlin.runCatching {
|
||||||
|
thread.submit {
|
||||||
|
kotlin.runCatching {
|
||||||
|
lineReader.readLine(
|
||||||
|
if (hint.isNotEmpty()) {
|
||||||
|
lineReader.printAbove(
|
||||||
|
Ansi.ansi()
|
||||||
|
.fgCyan()
|
||||||
|
.a(
|
||||||
|
LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault())
|
||||||
|
.format(format)
|
||||||
|
)
|
||||||
|
.a(" ")
|
||||||
|
.fgMagenta().a(hint)
|
||||||
|
.reset()
|
||||||
|
.toString()
|
||||||
|
)
|
||||||
|
"$hint > "
|
||||||
|
} else "> "
|
||||||
|
)
|
||||||
|
}.let { result ->
|
||||||
|
executingCoroutine = null
|
||||||
|
coroutine.resumeWith(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.onFailure { error ->
|
||||||
|
executingCoroutine = null
|
||||||
|
kotlin.runCatching { coroutine.resumeWithException(EndOfFileException(error)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,12 +5,13 @@
|
|||||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||||
*
|
*
|
||||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* @author Karlatemp <karlatemp@vip.qq.com> <https://github.com/Karlatemp>
|
* @author Karlatemp <karlatemp@vip.qq.com> <https://github.com/Karlatemp>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.mamoe.mirai.console.pure
|
package net.mamoe.mirai.console.terminal
|
||||||
|
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
@ -23,10 +24,10 @@ package net.mamoe.mirai.console.pure
|
|||||||
AnnotationTarget.CONSTRUCTOR
|
AnnotationTarget.CONSTRUCTOR
|
||||||
)
|
)
|
||||||
@MustBeDocumented
|
@MustBeDocumented
|
||||||
annotation class ConsolePureExperimentalApi
|
annotation class ConsoleTerminalExperimentalApi
|
||||||
|
|
||||||
@ConsolePureExperimentalApi
|
@ConsoleTerminalExperimentalApi
|
||||||
public object ConsolePureSettings {
|
public object ConsoleTerminalSettings {
|
||||||
@JvmField
|
@JvmField
|
||||||
var setupAnsi: Boolean = System.getProperty("os.name")
|
var setupAnsi: Boolean = System.getProperty("os.name")
|
||||||
.toLowerCase()
|
.toLowerCase()
|
@ -5,13 +5,14 @@
|
|||||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||||
*
|
*
|
||||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.mamoe.mirai.console.pure
|
package net.mamoe.mirai.console.terminal
|
||||||
|
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineName
|
import kotlinx.coroutines.CoroutineName
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.mamoe.mirai.console.MiraiConsole
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
import net.mamoe.mirai.console.command.BuiltInCommands
|
import net.mamoe.mirai.console.command.BuiltInCommands
|
||||||
@ -20,18 +21,33 @@ import net.mamoe.mirai.console.command.CommandExecuteStatus
|
|||||||
import net.mamoe.mirai.console.command.CommandManager
|
import net.mamoe.mirai.console.command.CommandManager
|
||||||
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand
|
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.executeCommand
|
||||||
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
||||||
|
import net.mamoe.mirai.console.terminal.noconsole.NoConsole
|
||||||
import net.mamoe.mirai.console.util.ConsoleInternalApi
|
import net.mamoe.mirai.console.util.ConsoleInternalApi
|
||||||
import net.mamoe.mirai.console.util.requestInput
|
import net.mamoe.mirai.console.util.requestInput
|
||||||
import net.mamoe.mirai.utils.DefaultLogger
|
import net.mamoe.mirai.utils.DefaultLogger
|
||||||
|
import org.jline.reader.EndOfFileException
|
||||||
import org.jline.reader.UserInterruptException
|
import org.jline.reader.UserInterruptException
|
||||||
|
|
||||||
val consoleLogger by lazy { DefaultLogger("console") }
|
val consoleLogger by lazy { DefaultLogger("console") }
|
||||||
|
|
||||||
@OptIn(ConsoleInternalApi::class, ConsolePureExperimentalApi::class)
|
@OptIn(ConsoleInternalApi::class, ConsoleTerminalExperimentalApi::class)
|
||||||
internal fun startupConsoleThread() {
|
internal fun startupConsoleThread() {
|
||||||
if (ConsolePureSettings.noConsole) return
|
if (terminal is NoConsole) return
|
||||||
|
|
||||||
MiraiConsole.launch(CoroutineName("Input")) {
|
MiraiConsole.launch(CoroutineName("Input Cancelling Daemon")) {
|
||||||
|
while (true) {
|
||||||
|
delay(2000)
|
||||||
|
}
|
||||||
|
}.invokeOnCompletion {
|
||||||
|
runCatching<Unit> {
|
||||||
|
terminal.close()
|
||||||
|
ConsoleInputImpl.thread.shutdownNow()
|
||||||
|
runCatching {
|
||||||
|
ConsoleInputImpl.executingCoroutine?.cancel(EndOfFileException())
|
||||||
|
}
|
||||||
|
}.exceptionOrNull()?.printStackTrace()
|
||||||
|
}
|
||||||
|
MiraiConsole.launch(CoroutineName("Console Command")) {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
val next = MiraiConsole.requestInput("").let {
|
val next = MiraiConsole.requestInput("").let {
|
||||||
@ -65,17 +81,14 @@ internal fun startupConsoleThread() {
|
|||||||
} catch (e: CancellationException) {
|
} catch (e: CancellationException) {
|
||||||
return@launch
|
return@launch
|
||||||
} catch (e: UserInterruptException) {
|
} catch (e: UserInterruptException) {
|
||||||
MiraiConsole.cancel()
|
BuiltInCommands.StopCommand.run { ConsoleCommandSender.handle() }
|
||||||
|
return@launch
|
||||||
|
} catch (eof: EndOfFileException) {
|
||||||
|
consoleLogger.warning("Closing input service...")
|
||||||
return@launch
|
return@launch
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
consoleLogger.error("Unhandled exception", e)
|
consoleLogger.error("Unhandled exception", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MiraiConsole.job.invokeOnCompletion {
|
|
||||||
runCatching {
|
|
||||||
terminal.close()
|
|
||||||
}.exceptionOrNull()?.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -5,6 +5,7 @@
|
|||||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||||
*
|
*
|
||||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:Suppress(
|
@file:Suppress(
|
||||||
@ -17,13 +18,16 @@
|
|||||||
"INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING",
|
"INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING",
|
||||||
"EXPOSED_SUPER_CLASS"
|
"EXPOSED_SUPER_CLASS"
|
||||||
)
|
)
|
||||||
@file:OptIn(ConsoleInternalApi::class, ConsoleFrontEndImplementation::class, ConsolePureExperimentalApi::class)
|
@file:OptIn(ConsoleInternalApi::class, ConsoleFrontEndImplementation::class, ConsoleTerminalExperimentalApi::class)
|
||||||
|
|
||||||
package net.mamoe.mirai.console.pure
|
package net.mamoe.mirai.console.terminal
|
||||||
|
|
||||||
|
|
||||||
import com.vdurmont.semver4j.Semver
|
import com.vdurmont.semver4j.Semver
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.CancellationException
|
||||||
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
|
import kotlinx.coroutines.CoroutineName
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
|
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
|
||||||
import net.mamoe.mirai.console.MiraiConsole
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription
|
import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription
|
||||||
@ -32,10 +36,10 @@ import net.mamoe.mirai.console.data.MultiFilePluginDataStorage
|
|||||||
import net.mamoe.mirai.console.data.PluginDataStorage
|
import net.mamoe.mirai.console.data.PluginDataStorage
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader
|
import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader
|
||||||
import net.mamoe.mirai.console.plugin.loader.PluginLoader
|
import net.mamoe.mirai.console.plugin.loader.PluginLoader
|
||||||
import net.mamoe.mirai.console.pure.ConsoleInputImpl.requestInput
|
import net.mamoe.mirai.console.terminal.ConsoleInputImpl.requestInput
|
||||||
|
import net.mamoe.mirai.console.terminal.noconsole.AllEmptyLineReader
|
||||||
|
import net.mamoe.mirai.console.terminal.noconsole.NoConsole
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||||
import net.mamoe.mirai.console.pure.noconsole.AllEmptyLineReader
|
|
||||||
import net.mamoe.mirai.console.pure.noconsole.NoConsole
|
|
||||||
import net.mamoe.mirai.console.util.ConsoleInput
|
import net.mamoe.mirai.console.util.ConsoleInput
|
||||||
import net.mamoe.mirai.console.util.ConsoleInternalApi
|
import net.mamoe.mirai.console.util.ConsoleInternalApi
|
||||||
import net.mamoe.mirai.console.util.NamedSupervisorJob
|
import net.mamoe.mirai.console.util.NamedSupervisorJob
|
||||||
@ -46,31 +50,28 @@ import org.jline.reader.LineReaderBuilder
|
|||||||
import org.jline.reader.impl.completer.NullCompleter
|
import org.jline.reader.impl.completer.NullCompleter
|
||||||
import org.jline.terminal.Terminal
|
import org.jline.terminal.Terminal
|
||||||
import org.jline.terminal.TerminalBuilder
|
import org.jline.terminal.TerminalBuilder
|
||||||
|
import org.jline.terminal.impl.AbstractWindowsTerminal
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.time.Instant
|
|
||||||
import java.time.LocalDateTime
|
|
||||||
import java.time.ZoneId
|
|
||||||
import java.time.format.DateTimeFormatter
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mirai-console-pure 后端实现
|
* mirai-console-terminal 后端实现
|
||||||
*
|
*
|
||||||
* @see MiraiConsolePureLoader CLI 入口点
|
* @see MiraiConsoleTerminalLoader CLI 入口点
|
||||||
*/
|
*/
|
||||||
@ConsoleExperimentalApi
|
@ConsoleExperimentalApi
|
||||||
class MiraiConsoleImplementationPure
|
class MiraiConsoleImplementationTerminal
|
||||||
@JvmOverloads constructor(
|
@JvmOverloads constructor(
|
||||||
override val rootPath: Path = Paths.get(".").toAbsolutePath(),
|
override val rootPath: Path = Paths.get(".").toAbsolutePath(),
|
||||||
override val builtInPluginLoaders: List<Lazy<PluginLoader<*, *>>> = listOf(lazy { JvmPluginLoader }),
|
override val builtInPluginLoaders: List<Lazy<PluginLoader<*, *>>> = listOf(lazy { JvmPluginLoader }),
|
||||||
override val frontEndDescription: MiraiConsoleFrontEndDescription = ConsoleFrontEndDescImpl,
|
override val frontEndDescription: MiraiConsoleFrontEndDescription = ConsoleFrontEndDescImpl,
|
||||||
override val consoleCommandSender: MiraiConsoleImplementation.ConsoleCommandSenderImpl = ConsoleCommandSenderImplPure,
|
override val consoleCommandSender: MiraiConsoleImplementation.ConsoleCommandSenderImpl = ConsoleCommandSenderImplTerminal,
|
||||||
override val dataStorageForJvmPluginLoader: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("data")),
|
override val dataStorageForJvmPluginLoader: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("data")),
|
||||||
override val dataStorageForBuiltIns: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("data")),
|
override val dataStorageForBuiltIns: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("data")),
|
||||||
override val configStorageForJvmPluginLoader: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("config")),
|
override val configStorageForJvmPluginLoader: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("config")),
|
||||||
override val configStorageForBuiltIns: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("config")),
|
override val configStorageForBuiltIns: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("config")),
|
||||||
) : MiraiConsoleImplementation, CoroutineScope by CoroutineScope(
|
) : MiraiConsoleImplementation, CoroutineScope by CoroutineScope(
|
||||||
NamedSupervisorJob("MiraiConsoleImplementationPure") +
|
NamedSupervisorJob("MiraiConsoleImplementationTerminal") +
|
||||||
CoroutineExceptionHandler { coroutineContext, throwable ->
|
CoroutineExceptionHandler { coroutineContext, throwable ->
|
||||||
if (throwable is CancellationException) {
|
if (throwable is CancellationException) {
|
||||||
return@CoroutineExceptionHandler
|
return@CoroutineExceptionHandler
|
||||||
@ -94,30 +95,9 @@ class MiraiConsoleImplementationPure
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private object ConsoleInputImpl : ConsoleInput {
|
|
||||||
private val format = DateTimeFormatter.ofPattern("HH:mm:ss")
|
|
||||||
|
|
||||||
override suspend fun requestInput(hint: String): String {
|
|
||||||
return withContext(Dispatchers.IO) {
|
|
||||||
lineReader.readLine(
|
|
||||||
if (hint.isNotEmpty()) {
|
|
||||||
lineReader.printAbove(
|
|
||||||
Ansi.ansi()
|
|
||||||
.fgCyan().a(LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault()).format(format))
|
|
||||||
.a(" ")
|
|
||||||
.fgMagenta().a(hint)
|
|
||||||
.reset()
|
|
||||||
.toString()
|
|
||||||
)
|
|
||||||
"$hint > "
|
|
||||||
} else "> "
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val lineReader: LineReader by lazy {
|
val lineReader: LineReader by lazy {
|
||||||
if (ConsolePureSettings.noConsole) return@lazy AllEmptyLineReader
|
val terminal = terminal
|
||||||
|
if (terminal is NoConsole) return@lazy AllEmptyLineReader
|
||||||
|
|
||||||
LineReaderBuilder.builder()
|
LineReaderBuilder.builder()
|
||||||
.terminal(terminal)
|
.terminal(terminal)
|
||||||
@ -126,7 +106,7 @@ val lineReader: LineReader by lazy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val terminal: Terminal = run {
|
val terminal: Terminal = run {
|
||||||
if (ConsolePureSettings.noConsole) return@run NoConsole
|
if (ConsoleTerminalSettings.noConsole) return@run NoConsole
|
||||||
|
|
||||||
val dumb = System.getProperty("java.class.path")
|
val dumb = System.getProperty("java.class.path")
|
||||||
.contains("idea_rt.jar") || System.getProperty("mirai.idea") !== null || System.getenv("mirai.idea") !== null
|
.contains("idea_rt.jar") || System.getProperty("mirai.idea") !== null || System.getenv("mirai.idea") !== null
|
||||||
@ -134,7 +114,33 @@ val terminal: Terminal = run {
|
|||||||
runCatching {
|
runCatching {
|
||||||
TerminalBuilder.builder()
|
TerminalBuilder.builder()
|
||||||
.dumb(dumb)
|
.dumb(dumb)
|
||||||
|
.paused(true)
|
||||||
.build()
|
.build()
|
||||||
|
.let { terminal ->
|
||||||
|
if (terminal is AbstractWindowsTerminal) {
|
||||||
|
val pumpField = runCatching {
|
||||||
|
AbstractWindowsTerminal::class.java.getDeclaredField("pump").also {
|
||||||
|
it.isAccessible = true
|
||||||
|
}
|
||||||
|
}.onFailure { err ->
|
||||||
|
err.printStackTrace()
|
||||||
|
return@let terminal.also { it.resume() }
|
||||||
|
}.getOrThrow()
|
||||||
|
var response = terminal
|
||||||
|
terminal.setOnClose {
|
||||||
|
response = NoConsole
|
||||||
|
}
|
||||||
|
terminal.resume()
|
||||||
|
val pumpThread = pumpField[terminal] as? Thread ?: return@let NoConsole
|
||||||
|
@Suppress("ControlFlowWithEmptyBody")
|
||||||
|
while (pumpThread.state == Thread.State.NEW);
|
||||||
|
Thread.sleep(1000)
|
||||||
|
terminal.setOnClose(null)
|
||||||
|
return@let response
|
||||||
|
}
|
||||||
|
terminal.resume()
|
||||||
|
terminal
|
||||||
|
}
|
||||||
}.recoverCatching {
|
}.recoverCatching {
|
||||||
TerminalBuilder.builder()
|
TerminalBuilder.builder()
|
||||||
.jansi(true)
|
.jansi(true)
|
||||||
@ -147,7 +153,7 @@ val terminal: Terminal = run {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private object ConsoleFrontEndDescImpl : MiraiConsoleFrontEndDescription {
|
private object ConsoleFrontEndDescImpl : MiraiConsoleFrontEndDescription {
|
||||||
override val name: String get() = "Pure"
|
override val name: String get() = "Terminal"
|
||||||
override val vendor: String get() = "Mamoe Technologies"
|
override val vendor: String get() = "Mamoe Technologies"
|
||||||
override val version: Semver = net.mamoe.mirai.console.internal.MiraiConsoleBuildConstants.version
|
override val version: Semver = net.mamoe.mirai.console.internal.MiraiConsoleBuildConstants.version
|
||||||
}
|
}
|
@ -5,6 +5,7 @@
|
|||||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
|
||||||
*
|
*
|
||||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:Suppress(
|
@file:Suppress(
|
||||||
@ -15,9 +16,9 @@
|
|||||||
"INVISIBLE_GETTER",
|
"INVISIBLE_GETTER",
|
||||||
"INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER",
|
"INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER",
|
||||||
)
|
)
|
||||||
@file:OptIn(ConsoleInternalApi::class, ConsolePureExperimentalApi::class)
|
@file:OptIn(ConsoleInternalApi::class, ConsoleTerminalExperimentalApi::class)
|
||||||
|
|
||||||
package net.mamoe.mirai.console.pure
|
package net.mamoe.mirai.console.terminal
|
||||||
|
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -26,20 +27,22 @@ import net.mamoe.mirai.console.MiraiConsole
|
|||||||
import net.mamoe.mirai.console.MiraiConsoleImplementation
|
import net.mamoe.mirai.console.MiraiConsoleImplementation
|
||||||
import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
|
import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
|
||||||
import net.mamoe.mirai.console.data.AutoSavePluginDataHolder
|
import net.mamoe.mirai.console.data.AutoSavePluginDataHolder
|
||||||
import net.mamoe.mirai.console.pure.noconsole.SystemOutputPrintStream
|
import net.mamoe.mirai.console.terminal.noconsole.SystemOutputPrintStream
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
|
||||||
import net.mamoe.mirai.console.util.ConsoleInternalApi
|
import net.mamoe.mirai.console.util.ConsoleInternalApi
|
||||||
import net.mamoe.mirai.console.util.CoroutineScopeUtils.childScope
|
import net.mamoe.mirai.console.util.CoroutineScopeUtils.childScope
|
||||||
import net.mamoe.mirai.message.data.Message
|
import net.mamoe.mirai.message.data.Message
|
||||||
import net.mamoe.mirai.utils.DefaultLogger
|
import net.mamoe.mirai.utils.DefaultLogger
|
||||||
import net.mamoe.mirai.utils.minutesToMillis
|
import net.mamoe.mirai.utils.minutesToMillis
|
||||||
|
import java.io.FileDescriptor
|
||||||
|
import java.io.FileOutputStream
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mirai-console-pure CLI 入口点
|
* mirai-console-terminal CLI 入口点
|
||||||
*/
|
*/
|
||||||
object MiraiConsolePureLoader {
|
object MiraiConsoleTerminalLoader {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
parse(args, exitProcess = true)
|
parse(args, exitProcess = true)
|
||||||
@ -53,10 +56,10 @@ object MiraiConsolePureLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConsolePureExperimentalApi
|
@ConsoleTerminalExperimentalApi
|
||||||
fun printHelpMessage() {
|
fun printHelpMessage() {
|
||||||
val help = listOf(
|
val help = listOf(
|
||||||
"" to "Mirai-Console[Pure FrontEnd] v" + kotlin.runCatching {
|
"" to "Mirai-Console[Terminal FrontEnd] v" + kotlin.runCatching {
|
||||||
net.mamoe.mirai.console.internal.MiraiConsoleBuildConstants.version
|
net.mamoe.mirai.console.internal.MiraiConsoleBuildConstants.version
|
||||||
}.getOrElse { "<unknown>" },
|
}.getOrElse { "<unknown>" },
|
||||||
"" to "",
|
"" to "",
|
||||||
@ -96,7 +99,7 @@ object MiraiConsolePureLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConsolePureExperimentalApi
|
@ConsoleTerminalExperimentalApi
|
||||||
fun parse(args: Array<String>, exitProcess: Boolean = false) {
|
fun parse(args: Array<String>, exitProcess: Boolean = false) {
|
||||||
val iterator = args.iterator()
|
val iterator = args.iterator()
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
@ -107,19 +110,19 @@ object MiraiConsolePureLoader {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
"--no-console" -> {
|
"--no-console" -> {
|
||||||
ConsolePureSettings.noConsole = true
|
ConsoleTerminalSettings.noConsole = true
|
||||||
}
|
}
|
||||||
"--dont-setup-terminal-ansi" -> {
|
"--dont-setup-terminal-ansi" -> {
|
||||||
ConsolePureSettings.setupAnsi = false
|
ConsoleTerminalSettings.setupAnsi = false
|
||||||
}
|
}
|
||||||
"--no-ansi" -> {
|
"--no-ansi" -> {
|
||||||
ConsolePureSettings.noAnsi = true
|
ConsoleTerminalSettings.noAnsi = true
|
||||||
ConsolePureSettings.setupAnsi = false
|
ConsoleTerminalSettings.setupAnsi = false
|
||||||
}
|
}
|
||||||
"--reading-replacement" -> {
|
"--reading-replacement" -> {
|
||||||
ConsolePureSettings.noConsoleSafeReading = true
|
ConsoleTerminalSettings.noConsoleSafeReading = true
|
||||||
if (iterator.hasNext()) {
|
if (iterator.hasNext()) {
|
||||||
ConsolePureSettings.noConsoleReadingReplacement = iterator.next()
|
ConsoleTerminalSettings.noConsoleReadingReplacement = iterator.next()
|
||||||
} else {
|
} else {
|
||||||
println("Bad option `--reading-replacement`")
|
println("Bad option `--reading-replacement`")
|
||||||
println("Usage: --reading-replacement <string>")
|
println("Usage: --reading-replacement <string>")
|
||||||
@ -129,7 +132,7 @@ object MiraiConsolePureLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"--safe-reading" -> {
|
"--safe-reading" -> {
|
||||||
ConsolePureSettings.noConsoleSafeReading = true
|
ConsoleTerminalSettings.noConsoleSafeReading = true
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
println("Unknown option `$option`")
|
println("Unknown option `$option`")
|
||||||
@ -140,13 +143,13 @@ object MiraiConsolePureLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ConsolePureSettings.noConsole)
|
if (ConsoleTerminalSettings.noConsole)
|
||||||
SystemOutputPrintStream // Setup Output Channel
|
SystemOutputPrintStream // Setup Output Channel
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
@ConsoleExperimentalApi
|
@ConsoleExperimentalApi
|
||||||
fun startAsDaemon(instance: MiraiConsoleImplementationPure = MiraiConsoleImplementationPure()) {
|
fun startAsDaemon(instance: MiraiConsoleImplementationTerminal = MiraiConsoleImplementationTerminal()) {
|
||||||
instance.start()
|
instance.start()
|
||||||
overrideSTD()
|
overrideSTD()
|
||||||
startupConsoleThread()
|
startupConsoleThread()
|
||||||
@ -160,7 +163,7 @@ internal object ConsoleDataHolder : AutoSavePluginDataHolder,
|
|||||||
|
|
||||||
@ConsoleExperimentalApi
|
@ConsoleExperimentalApi
|
||||||
override val dataHolderName: String
|
override val dataHolderName: String
|
||||||
get() = "Pure"
|
get() = "Terminal"
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun overrideSTD() {
|
internal fun overrideSTD() {
|
||||||
@ -181,12 +184,16 @@ internal fun overrideSTD() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal object ConsoleCommandSenderImplPure : MiraiConsoleImplementation.ConsoleCommandSenderImpl {
|
internal object ConsoleCommandSenderImplTerminal : MiraiConsoleImplementation.ConsoleCommandSenderImpl {
|
||||||
override suspend fun sendMessage(message: String) {
|
override suspend fun sendMessage(message: String) {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
lineReader.printAbove(message)
|
lineReader.printAbove(message)
|
||||||
}.onFailure {
|
}.onFailure { exception ->
|
||||||
consoleLogger.error("Exception while ConsoleCommandSenderImplPure.sendMessage", it)
|
// If failed. It means JLine Terminal not working...
|
||||||
|
PrintStream(FileOutputStream(FileDescriptor.err)).use {
|
||||||
|
it.println("Exception while ConsoleCommandSenderImplTerminal.sendMessage")
|
||||||
|
exception.printStackTrace(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -10,12 +10,12 @@
|
|||||||
/*
|
/*
|
||||||
* @author Karlatemp <karlatemp@vip.qq.com> <https://github.com/Karlatemp>
|
* @author Karlatemp <karlatemp@vip.qq.com> <https://github.com/Karlatemp>
|
||||||
*/
|
*/
|
||||||
@file:OptIn(ConsolePureExperimentalApi::class)
|
@file:OptIn(ConsoleTerminalExperimentalApi::class)
|
||||||
|
|
||||||
package net.mamoe.mirai.console.pure.noconsole
|
package net.mamoe.mirai.console.terminal.noconsole
|
||||||
|
|
||||||
import net.mamoe.mirai.console.pure.ConsolePureExperimentalApi
|
import net.mamoe.mirai.console.terminal.ConsoleTerminalExperimentalApi
|
||||||
import net.mamoe.mirai.console.pure.ConsolePureSettings
|
import net.mamoe.mirai.console.terminal.ConsoleTerminalSettings
|
||||||
import org.jline.keymap.KeyMap
|
import org.jline.keymap.KeyMap
|
||||||
import org.jline.reader.*
|
import org.jline.reader.*
|
||||||
import org.jline.terminal.Attributes
|
import org.jline.terminal.Attributes
|
||||||
@ -69,8 +69,8 @@ internal object AllIgnoredOutputStream : OutputStream() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal val SystemOutputPrintStream by lazy {
|
internal val SystemOutputPrintStream by lazy {
|
||||||
@OptIn(ConsolePureExperimentalApi::class)
|
@OptIn(ConsoleTerminalExperimentalApi::class)
|
||||||
if (ConsolePureSettings.setupAnsi) {
|
if (ConsoleTerminalSettings.setupAnsi) {
|
||||||
org.fusesource.jansi.AnsiConsole.systemInstall()
|
org.fusesource.jansi.AnsiConsole.systemInstall()
|
||||||
}
|
}
|
||||||
System.out
|
System.out
|
||||||
@ -81,16 +81,16 @@ internal object AllEmptyLineReader : LineReader {
|
|||||||
|
|
||||||
override fun printAbove(str: String?) {
|
override fun printAbove(str: String?) {
|
||||||
if (str == null) return
|
if (str == null) return
|
||||||
@OptIn(ConsolePureExperimentalApi::class)
|
@OptIn(ConsoleTerminalExperimentalApi::class)
|
||||||
if (ConsolePureSettings.noAnsi) {
|
if (ConsoleTerminalSettings.noAnsi) {
|
||||||
SystemOutputPrintStream.println(ANSI_REGEX.replace(str, ""))
|
SystemOutputPrintStream.println(ANSI_REGEX.replace(str, ""))
|
||||||
} else SystemOutputPrintStream.println(str)
|
} else SystemOutputPrintStream.println(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ConsolePureExperimentalApi::class)
|
@OptIn(ConsoleTerminalExperimentalApi::class)
|
||||||
override fun readLine(): String =
|
override fun readLine(): String =
|
||||||
if (ConsolePureSettings.noConsoleSafeReading) ConsolePureSettings.noConsoleReadingReplacement
|
if (ConsoleTerminalSettings.noConsoleSafeReading) ConsoleTerminalSettings.noConsoleReadingReplacement
|
||||||
else error("Unsupported Reading line when console front-end closed.")
|
else throw EndOfFileException("Unsupported Reading line when console front-end closed.")
|
||||||
|
|
||||||
// region
|
// region
|
||||||
private fun <T> ignored(): T = error("Ignored")
|
private fun <T> ignored(): T = error("Ignored")
|
@ -19,7 +19,7 @@ fun includeProject(projectPath: String, path: String? = null) {
|
|||||||
|
|
||||||
includeProject(":mirai-console", "backend/mirai-console")
|
includeProject(":mirai-console", "backend/mirai-console")
|
||||||
includeProject(":mirai-console.codegen", "backend/codegen")
|
includeProject(":mirai-console.codegen", "backend/codegen")
|
||||||
includeProject(":mirai-console-pure", "frontend/mirai-console-pure")
|
includeProject(":mirai-console-terminal", "frontend/mirai-console-terminal")
|
||||||
includeProject(":mirai-console-compiler-common", "tools/compiler-common")
|
includeProject(":mirai-console-compiler-common", "tools/compiler-common")
|
||||||
includeProject(":mirai-console-intellij", "tools/intellij-plugin")
|
includeProject(":mirai-console-intellij", "tools/intellij-plugin")
|
||||||
includeProject(":mirai-console-gradle", "tools/gradle-plugin")
|
includeProject(":mirai-console-gradle", "tools/gradle-plugin")
|
||||||
|
@ -2,11 +2,11 @@ import net.mamoe.mirai.alsoLogin
|
|||||||
import net.mamoe.mirai.console.MiraiConsole
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.enable
|
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.enable
|
||||||
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.load
|
import net.mamoe.mirai.console.plugin.PluginManager.INSTANCE.load
|
||||||
import net.mamoe.mirai.console.pure.MiraiConsolePureLoader
|
import net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader
|
||||||
import org.example.myplugin.MyPluginMain
|
import org.example.myplugin.MyPluginMain
|
||||||
|
|
||||||
suspend fun main() {
|
suspend fun main() {
|
||||||
MiraiConsolePureLoader.startAsDaemon()
|
MiraiConsoleTerminalLoader.startAsDaemon()
|
||||||
|
|
||||||
MyPluginMain.load() // 主动加载插件, Console 会调用 MyPluginMain.onLoad
|
MyPluginMain.load() // 主动加载插件, Console 会调用 MyPluginMain.onLoad
|
||||||
MyPluginMain.enable() // 主动启用插件, Console 会调用 MyPluginMain.onEnable
|
MyPluginMain.enable() // 主动启用插件, Console 会调用 MyPluginMain.onEnable
|
||||||
|
Loading…
Reference in New Issue
Block a user