mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-26 07:20:09 +08:00
Fix unmanaged coroutine job, add names to all CoroutineScopes
This commit is contained in:
parent
c479856380
commit
bbf2ead3f0
@ -108,7 +108,7 @@ public interface MiraiConsole : CoroutineScope {
|
|||||||
Bot(id, password) {
|
Bot(id, password) {
|
||||||
fileBasedDeviceInfo()
|
fileBasedDeviceInfo()
|
||||||
redirectNetworkLogToDirectory()
|
redirectNetworkLogToDirectory()
|
||||||
parentCoroutineContext = MiraiConsole.childScopeContext()
|
parentCoroutineContext = MiraiConsole.childScopeContext("Bot $id")
|
||||||
|
|
||||||
this.loginSolver = MiraiConsoleImplementationBridge.createLoginSolver(id, this)
|
this.loginSolver = MiraiConsoleImplementationBridge.createLoginSolver(id, this)
|
||||||
configuration()
|
configuration()
|
||||||
|
@ -27,6 +27,7 @@ import net.mamoe.mirai.console.util.BotManager.INSTANCE.removeManager
|
|||||||
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.contact.*
|
import net.mamoe.mirai.contact.*
|
||||||
|
import net.mamoe.mirai.event.events.EventCancelledException
|
||||||
import net.mamoe.mirai.getFriendOrNull
|
import net.mamoe.mirai.getFriendOrNull
|
||||||
import net.mamoe.mirai.message.nextMessageOrNull
|
import net.mamoe.mirai.message.nextMessageOrNull
|
||||||
import net.mamoe.mirai.utils.secondsToMillis
|
import net.mamoe.mirai.utils.secondsToMillis
|
||||||
@ -113,19 +114,27 @@ public object BuiltInCommands {
|
|||||||
|
|
||||||
@Handler
|
@Handler
|
||||||
public suspend fun CommandSender.handle() {
|
public suspend fun CommandSender.handle() {
|
||||||
closingLock.withLock {
|
kotlin.runCatching {
|
||||||
sendMessage("Stopping mirai-console")
|
closingLock.withLock {
|
||||||
kotlin.runCatching {
|
sendMessage("Stopping mirai-console")
|
||||||
MiraiConsole.job.cancelAndJoin()
|
kotlin.runCatching {
|
||||||
}.fold(
|
MiraiConsole.job.cancelAndJoin()
|
||||||
onSuccess = { sendMessage("mirai-console stopped successfully.") },
|
}.fold(
|
||||||
onFailure = {
|
onSuccess = {
|
||||||
@OptIn(ConsoleInternalAPI::class)
|
ignoreException<EventCancelledException> { sendMessage("mirai-console stopped successfully.") }
|
||||||
MiraiConsole.mainLogger.error(it)
|
},
|
||||||
sendMessage(it.localizedMessage ?: it.message ?: it.toString())
|
onFailure = {
|
||||||
}
|
@OptIn(ConsoleInternalAPI::class)
|
||||||
)
|
MiraiConsole.mainLogger.error(it)
|
||||||
}
|
ignoreException<EventCancelledException> {
|
||||||
|
sendMessage(
|
||||||
|
it.localizedMessage ?: it.message ?: it.toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.exceptionOrNull()?.let(MiraiConsole.mainLogger::error)
|
||||||
exitProcess(0)
|
exitProcess(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,6 +167,24 @@ public object BuiltInCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal inline fun <reified E : Throwable, R> ignoreException(block: () -> R): R? {
|
||||||
|
try {
|
||||||
|
return block()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (e is E) return null
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <reified E : Throwable> ignoreException(block: () -> Unit): Unit? {
|
||||||
|
try {
|
||||||
|
return block()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (e is E) return null
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun ContactOrBot.render(): String {
|
internal fun ContactOrBot.render(): String {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is Bot -> "Bot $nick($id)"
|
is Bot -> "Bot $nick($id)"
|
||||||
|
@ -28,6 +28,7 @@ public interface PluginDataHolder {
|
|||||||
/**
|
/**
|
||||||
* 保存时使用的分类名
|
* 保存时使用的分类名
|
||||||
*/
|
*/
|
||||||
|
@ConsoleExperimentalAPI
|
||||||
public val name: String
|
public val name: String
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ public interface AutoSavePluginDataHolder : PluginDataHolder, CoroutineScope {
|
|||||||
* @see LongRange Java 用户使用 [LongRange] 的构造器创建
|
* @see LongRange Java 用户使用 [LongRange] 的构造器创建
|
||||||
* @see Long.rangeTo Kotlin 用户使用 [Long.rangeTo] 创建, 如 `3000..50000`
|
* @see Long.rangeTo Kotlin 用户使用 [Long.rangeTo] 创建, 如 `3000..50000`
|
||||||
*/
|
*/
|
||||||
|
@ConsoleExperimentalAPI
|
||||||
public val autoSaveIntervalMillis: LongRange
|
public val autoSaveIntervalMillis: LongRange
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ internal object JarPluginLoaderImpl :
|
|||||||
get() = MiraiConsoleImplementationBridge.dataStorageForJarPluginLoader
|
get() = MiraiConsoleImplementationBridge.dataStorageForJarPluginLoader
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext =
|
override val coroutineContext: CoroutineContext =
|
||||||
MiraiConsole.childScopeContext(CoroutineExceptionHandler { _, throwable ->
|
MiraiConsole.childScopeContext("JarPluginLoader", CoroutineExceptionHandler { _, throwable ->
|
||||||
logger.error("Unhandled Jar plugin exception: ${throwable.message}", throwable)
|
logger.error("Unhandled Jar plugin exception: ${throwable.message}", throwable)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ import java.io.InputStream
|
|||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.coroutines.EmptyCoroutineContext
|
|
||||||
|
|
||||||
internal val <T> T.job: Job where T : CoroutineScope, T : Plugin get() = this.coroutineContext[Job]!!
|
internal val <T> T.job: Job where T : CoroutineScope, T : Plugin get() = this.coroutineContext[Job]!!
|
||||||
|
|
||||||
@ -119,14 +118,15 @@ internal abstract class JvmPluginInternal(
|
|||||||
|
|
||||||
// for future use
|
// for future use
|
||||||
@Suppress("PropertyName")
|
@Suppress("PropertyName")
|
||||||
@JvmField
|
internal val _intrinsicCoroutineContext: CoroutineContext by lazy {
|
||||||
internal var _intrinsicCoroutineContext: CoroutineContext = EmptyCoroutineContext
|
CoroutineName("Plugin $name")
|
||||||
|
}
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
internal val coroutineContextInitializer = {
|
internal val coroutineContextInitializer = {
|
||||||
CoroutineExceptionHandler { _, throwable -> logger.error(throwable) }
|
CoroutineExceptionHandler { _, throwable -> logger.error(throwable) }
|
||||||
.plus(parentCoroutineContext)
|
.plus(parentCoroutineContext)
|
||||||
.plus(SupervisorJob(parentCoroutineContext[Job]))
|
.plus(NamedSupervisorJob("Plugin $name", parentCoroutineContext[Job]))
|
||||||
.also {
|
.also {
|
||||||
JarPluginLoaderImpl.coroutineContext[Job]!!.invokeOnCompletion {
|
JarPluginLoaderImpl.coroutineContext[Job]!!.invokeOnCompletion {
|
||||||
this.cancel()
|
this.cancel()
|
||||||
@ -156,6 +156,16 @@ internal abstract class JvmPluginInternal(
|
|||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
internal class NamedSupervisorJob(
|
||||||
|
private val name: String,
|
||||||
|
parent: Job? = null
|
||||||
|
) : CompletableJob by SupervisorJob(parent) {
|
||||||
|
override fun toString(): String {
|
||||||
|
return "NamedSupervisorJob($name)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal inline fun AtomicLong.updateWhen(condition: (Long) -> Boolean, update: (Long) -> Long): Boolean {
|
internal inline fun AtomicLong.updateWhen(condition: (Long) -> Boolean, update: (Long) -> Long): Boolean {
|
||||||
while (true) {
|
while (true) {
|
||||||
val current = value
|
val current = value
|
||||||
|
@ -28,7 +28,7 @@ import java.io.File
|
|||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
|
|
||||||
internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsole.childScope() {
|
internal object PluginManagerImpl : PluginManager, CoroutineScope by MiraiConsole.childScope("PluginManager") {
|
||||||
|
|
||||||
override val pluginsPath: Path = MiraiConsole.rootPath.resolve("plugins").apply { mkdir() }
|
override val pluginsPath: Path = MiraiConsole.rootPath.resolve("plugins").apply { mkdir() }
|
||||||
override val pluginsFolder: File = pluginsPath.toFile()
|
override val pluginsFolder: File = pluginsPath.toFile()
|
||||||
|
@ -11,15 +11,16 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.console.internal.util
|
package net.mamoe.mirai.console.internal.util
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineName
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.Bot
|
||||||
import net.mamoe.mirai.console.MiraiConsole
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
import net.mamoe.mirai.console.data.*
|
import net.mamoe.mirai.console.data.*
|
||||||
import net.mamoe.mirai.console.data.PluginDataExtensions.mapKeys
|
import net.mamoe.mirai.console.data.PluginDataExtensions.mapKeys
|
||||||
import net.mamoe.mirai.console.data.PluginDataExtensions.withEmptyDefault
|
import net.mamoe.mirai.console.data.PluginDataExtensions.withEmptyDefault
|
||||||
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
|
||||||
|
import net.mamoe.mirai.console.internal.plugin.NamedSupervisorJob
|
||||||
import net.mamoe.mirai.console.util.BotManager
|
import net.mamoe.mirai.console.util.BotManager
|
||||||
import net.mamoe.mirai.contact.User
|
import net.mamoe.mirai.contact.User
|
||||||
import net.mamoe.mirai.utils.minutesToMillis
|
import net.mamoe.mirai.utils.minutesToMillis
|
||||||
@ -52,14 +53,25 @@ internal object ManagersConfig : AutoSavePluginConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal fun CoroutineContext.overrideWithSupervisorJob(): CoroutineContext = this + SupervisorJob(this[Job])
|
internal fun CoroutineContext.overrideWithSupervisorJob(name: String? = null): CoroutineContext =
|
||||||
internal fun CoroutineScope.childScope(context: CoroutineContext = EmptyCoroutineContext): CoroutineScope =
|
this + NamedSupervisorJob(name ?: "<unnamed>", this[Job])
|
||||||
CoroutineScope(this.childScopeContext(context))
|
|
||||||
|
|
||||||
internal fun CoroutineScope.childScopeContext(context: CoroutineContext = EmptyCoroutineContext): CoroutineContext =
|
internal fun CoroutineScope.childScope(
|
||||||
this.coroutineContext.overrideWithSupervisorJob() + context
|
name: String? = null,
|
||||||
|
context: CoroutineContext = EmptyCoroutineContext
|
||||||
|
): CoroutineScope =
|
||||||
|
CoroutineScope(this.childScopeContext(name, context))
|
||||||
|
|
||||||
internal object ConsoleDataScope : CoroutineScope by MiraiConsole.childScope() {
|
internal fun CoroutineScope.childScopeContext(
|
||||||
|
name: String? = null,
|
||||||
|
context: CoroutineContext = EmptyCoroutineContext
|
||||||
|
): CoroutineContext =
|
||||||
|
this.coroutineContext.overrideWithSupervisorJob(name) + context.let {
|
||||||
|
if (name != null) it + CoroutineName(name)
|
||||||
|
else it
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object ConsoleDataScope : CoroutineScope by MiraiConsole.childScope("ConsoleDataScope") {
|
||||||
private val data: Array<out PluginData> = arrayOf()
|
private val data: Array<out PluginData> = arrayOf()
|
||||||
private val configs: Array<out PluginConfig> = arrayOf(ManagersConfig)
|
private val configs: Array<out PluginConfig> = arrayOf(ManagersConfig)
|
||||||
|
|
||||||
@ -74,13 +86,13 @@ internal object ConsoleDataScope : CoroutineScope by MiraiConsole.childScope() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal object ConsoleBuiltInPluginDataHolder : AutoSavePluginDataHolder,
|
internal object ConsoleBuiltInPluginDataHolder : AutoSavePluginDataHolder,
|
||||||
CoroutineScope by ConsoleDataScope.childScope() {
|
CoroutineScope by ConsoleDataScope.childScope("ConsoleBuiltInPluginDataHolder") {
|
||||||
override val autoSaveIntervalMillis: LongRange = 1.minutesToMillis..10.minutesToMillis
|
override val autoSaveIntervalMillis: LongRange = 1.minutesToMillis..10.minutesToMillis
|
||||||
override val name: String get() = "ConsoleBuiltIns"
|
override val name: String get() = "ConsoleBuiltIns"
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object ConsoleBuiltInPluginConfigHolder : AutoSavePluginDataHolder,
|
internal object ConsoleBuiltInPluginConfigHolder : AutoSavePluginDataHolder,
|
||||||
CoroutineScope by ConsoleDataScope.childScope() {
|
CoroutineScope by ConsoleDataScope.childScope("ConsoleBuiltInPluginConfigHolder") {
|
||||||
override val autoSaveIntervalMillis: LongRange = 1.minutesToMillis..10.minutesToMillis
|
override val autoSaveIntervalMillis: LongRange = 1.minutesToMillis..10.minutesToMillis
|
||||||
override val name: String get() = "ConsoleBuiltIns"
|
override val name: String get() = "ConsoleBuiltIns"
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ package net.mamoe.mirai.console.internal.util
|
|||||||
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.future.future
|
import kotlinx.coroutines.future.future
|
||||||
|
import net.mamoe.mirai.console.internal.plugin.NamedSupervisorJob
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JavaPluginScheduler
|
import net.mamoe.mirai.console.plugin.jvm.JavaPluginScheduler
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
@ -20,7 +21,7 @@ import kotlin.coroutines.CoroutineContext
|
|||||||
internal class JavaPluginSchedulerImpl internal constructor(parentCoroutineContext: CoroutineContext) : CoroutineScope,
|
internal class JavaPluginSchedulerImpl internal constructor(parentCoroutineContext: CoroutineContext) : CoroutineScope,
|
||||||
JavaPluginScheduler {
|
JavaPluginScheduler {
|
||||||
override val coroutineContext: CoroutineContext =
|
override val coroutineContext: CoroutineContext =
|
||||||
parentCoroutineContext + SupervisorJob(parentCoroutineContext[Job])
|
parentCoroutineContext + NamedSupervisorJob(this.toString(), parentCoroutineContext[Job])
|
||||||
|
|
||||||
override fun repeating(intervalMs: Long, runnable: Runnable): Future<Void?> {
|
override fun repeating(intervalMs: Long, runnable: Runnable): Future<Void?> {
|
||||||
return this.future {
|
return this.future {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
package net.mamoe.mirai.console.plugin.jvm
|
package net.mamoe.mirai.console.plugin.jvm
|
||||||
|
|
||||||
import net.mamoe.mirai.console.internal.plugin.JvmPluginInternal
|
import net.mamoe.mirai.console.internal.plugin.JvmPluginInternal
|
||||||
|
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||||
import net.mamoe.mirai.utils.minutesToMillis
|
import net.mamoe.mirai.utils.minutesToMillis
|
||||||
import net.mamoe.mirai.utils.secondsToMillis
|
import net.mamoe.mirai.utils.secondsToMillis
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
@ -28,5 +29,6 @@ public abstract class AbstractJvmPlugin @JvmOverloads constructor(
|
|||||||
) : JvmPlugin, JvmPluginInternal(parentCoroutineContext) {
|
) : JvmPlugin, JvmPluginInternal(parentCoroutineContext) {
|
||||||
public final override val name: String get() = this.description.name
|
public final override val name: String get() = this.description.name
|
||||||
|
|
||||||
|
@ConsoleExperimentalAPI
|
||||||
public override val autoSaveIntervalMillis: LongRange = 30.secondsToMillis..10.minutesToMillis
|
public override val autoSaveIntervalMillis: LongRange = 30.secondsToMillis..10.minutesToMillis
|
||||||
}
|
}
|
@ -11,7 +11,7 @@ package net.mamoe.mirai.console.pure
|
|||||||
|
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.runBlocking
|
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
|
||||||
import net.mamoe.mirai.console.command.Command.Companion.primaryName
|
import net.mamoe.mirai.console.command.Command.Companion.primaryName
|
||||||
@ -22,71 +22,53 @@ 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.UserInterruptException
|
import org.jline.reader.UserInterruptException
|
||||||
import kotlin.concurrent.thread
|
|
||||||
|
|
||||||
val consoleLogger by lazy { DefaultLogger("console") }
|
val consoleLogger by lazy { DefaultLogger("console") }
|
||||||
|
|
||||||
@OptIn(ConsoleInternalAPI::class)
|
@OptIn(ConsoleInternalAPI::class)
|
||||||
internal fun startupConsoleThread() {
|
internal fun startupConsoleThread() {
|
||||||
|
MiraiConsole.launch {
|
||||||
val inputThread = thread(start = true, isDaemon = false, name = "Console Input") {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
runBlocking {
|
val next = MiraiConsole.requestInput("").let {
|
||||||
while (true) {
|
when {
|
||||||
try {
|
it.startsWith(CommandManager.commandPrefix) -> it
|
||||||
val next = MiraiConsole.requestInput("").let {
|
it == "?" -> CommandManager.commandPrefix + BuiltInCommands.Help.primaryName
|
||||||
when {
|
else -> CommandManager.commandPrefix + it
|
||||||
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.executeCommand(next)
|
|
||||||
when (result.status) {
|
|
||||||
CommandExecuteStatus.SUCCESSFUL -> {
|
|
||||||
}
|
|
||||||
CommandExecuteStatus.EXECUTION_EXCEPTION -> {
|
|
||||||
result.exception?.let(consoleLogger::error)
|
|
||||||
}
|
|
||||||
CommandExecuteStatus.COMMAND_NOT_FOUND -> {
|
|
||||||
consoleLogger.warning("未知指令: ${result.commandName}, 输入 ? 获取帮助")
|
|
||||||
}
|
|
||||||
CommandExecuteStatus.PERMISSION_DENIED -> {
|
|
||||||
consoleLogger.warning("Permission denied.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: InterruptedException) {
|
|
||||||
return@runBlocking
|
|
||||||
} catch (e: CancellationException) {
|
|
||||||
return@runBlocking
|
|
||||||
} catch (e: UserInterruptException) {
|
|
||||||
MiraiConsole.cancel()
|
|
||||||
return@runBlocking
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
consoleLogger.error("Unhandled exception", e)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (next.isBlank()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// consoleLogger.debug("INPUT> $next")
|
||||||
|
val result = ConsoleCommandSenderImpl.executeCommand(next)
|
||||||
|
when (result.status) {
|
||||||
|
CommandExecuteStatus.SUCCESSFUL -> {
|
||||||
|
}
|
||||||
|
CommandExecuteStatus.EXECUTION_EXCEPTION -> {
|
||||||
|
result.exception?.let(consoleLogger::error)
|
||||||
|
}
|
||||||
|
CommandExecuteStatus.COMMAND_NOT_FOUND -> {
|
||||||
|
consoleLogger.warning("未知指令: ${result.commandName}, 输入 ? 获取帮助")
|
||||||
|
}
|
||||||
|
CommandExecuteStatus.PERMISSION_DENIED -> {
|
||||||
|
consoleLogger.warning("Permission denied.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: InterruptedException) {
|
||||||
|
return@launch
|
||||||
|
} catch (e: CancellationException) {
|
||||||
|
return@launch
|
||||||
|
} catch (e: UserInterruptException) {
|
||||||
|
MiraiConsole.cancel()
|
||||||
|
return@launch
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
consoleLogger.error("Unhandled exception", e)
|
||||||
}
|
}
|
||||||
} catch (e: InterruptedException) {
|
|
||||||
return@thread
|
|
||||||
} catch (e: CancellationException) {
|
|
||||||
return@thread
|
|
||||||
} catch (e: UserInterruptException) {
|
|
||||||
MiraiConsole.cancel()
|
|
||||||
return@thread
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
consoleLogger.error("Unhandled exception", e)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MiraiConsole.job.invokeOnCompletion {
|
MiraiConsole.job.invokeOnCompletion {
|
||||||
runCatching {
|
|
||||||
inputThread.interrupt()
|
|
||||||
}.exceptionOrNull()?.printStackTrace()
|
|
||||||
runCatching {
|
runCatching {
|
||||||
terminal.close()
|
terminal.close()
|
||||||
}.exceptionOrNull()?.printStackTrace()
|
}.exceptionOrNull()?.printStackTrace()
|
||||||
|
@ -25,7 +25,6 @@ package net.mamoe.mirai.console.pure
|
|||||||
import com.vdurmont.semver4j.Semver
|
import com.vdurmont.semver4j.Semver
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
|
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
|
||||||
import net.mamoe.mirai.console.MiraiConsole
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
@ -34,6 +33,7 @@ import net.mamoe.mirai.console.MiraiConsoleImplementation
|
|||||||
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
import net.mamoe.mirai.console.command.ConsoleCommandSender
|
||||||
import net.mamoe.mirai.console.data.MultiFilePluginDataStorage
|
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.internal.plugin.NamedSupervisorJob
|
||||||
import net.mamoe.mirai.console.plugin.DeferredPluginLoader
|
import net.mamoe.mirai.console.plugin.DeferredPluginLoader
|
||||||
import net.mamoe.mirai.console.plugin.PluginLoader
|
import net.mamoe.mirai.console.plugin.PluginLoader
|
||||||
import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader
|
import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader
|
||||||
@ -72,7 +72,7 @@ internal class MiraiConsoleImplementationPure
|
|||||||
override val dataStorageForBuiltIns: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("data")),
|
override val dataStorageForBuiltIns: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("data")),
|
||||||
override val configStorageForJarPluginLoader: PluginDataStorage = MultiFilePluginDataStorage(rootPath.resolve("config")),
|
override val configStorageForJarPluginLoader: 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(SupervisorJob()) {
|
) : MiraiConsoleImplementation, CoroutineScope by CoroutineScope(NamedSupervisorJob("MiraiConsoleImplementationPure")) {
|
||||||
override val mainLogger: MiraiLogger by lazy {
|
override val mainLogger: MiraiLogger by lazy {
|
||||||
MiraiConsole.newLogger("main")
|
MiraiConsole.newLogger("main")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user