From a6e79fc204f094b03e99c03808e360e1af9c2f20 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sun, 14 Feb 2021 21:17:28 +0800 Subject: [PATCH 01/10] Release v2.4.0 --- .../mirai-console/src/internal/MiraiConsoleBuildConstants.kt | 4 ++-- tools/gradle-plugin/src/VersionConstants.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/mirai-console/src/internal/MiraiConsoleBuildConstants.kt b/backend/mirai-console/src/internal/MiraiConsoleBuildConstants.kt index 22afeaae1..2b82fcfe6 100644 --- a/backend/mirai-console/src/internal/MiraiConsoleBuildConstants.kt +++ b/backend/mirai-console/src/internal/MiraiConsoleBuildConstants.kt @@ -14,8 +14,8 @@ import java.time.Instant internal object MiraiConsoleBuildConstants { // auto-filled on build (task :mirai-console:fillBuildConstants) @JvmStatic - val buildDate: Instant = Instant.ofEpochSecond(1613042196) - const val versionConst: String = "2.4-RC" + val buildDate: Instant = Instant.ofEpochSecond(1613308312) + const val versionConst: String = "2.4.0" @JvmStatic val version: SemVersion = SemVersion(versionConst) diff --git a/tools/gradle-plugin/src/VersionConstants.kt b/tools/gradle-plugin/src/VersionConstants.kt index de2aac068..9734eaa79 100644 --- a/tools/gradle-plugin/src/VersionConstants.kt +++ b/tools/gradle-plugin/src/VersionConstants.kt @@ -10,6 +10,6 @@ package net.mamoe.mirai.console.gradle internal object VersionConstants { - const val CONSOLE_VERSION = "2.4-RC" // value is written here automatically during build - const val CORE_VERSION = "2.4-RC" // value is written here automatically during build + const val CONSOLE_VERSION = "2.4.0" // value is written here automatically during build + const val CORE_VERSION = "2.4.0" // value is written here automatically during build } \ No newline at end of file From 06564e91424c3e671fe1b9ee3f5515f47cc62425 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Mon, 15 Feb 2021 10:42:10 +0800 Subject: [PATCH 02/10] Update caller-finder version --- build.gradle.kts | 10 +++++++++- buildSrc/src/main/kotlin/Versions.kt | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index baa799d3d..52be20c93 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,12 @@ +/* + * Copyright 2019-2021 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("UnstableApiUsage") import org.jetbrains.kotlin.gradle.dsl.* @@ -26,7 +35,6 @@ allprojects { maven(url = "https://dl.bintray.com/kotlin/kotlin-eap") jcenter() mavenCentral() - maven(url = "https://dl.bintray.com/karlatemp/misc") } } diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index e4ba06292..24b9042f6 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -63,7 +63,7 @@ const val yamlkt = "net.mamoe.yamlkt:yamlkt:${Versions.yamlkt}" const val `jetbrains-annotations` = "org.jetbrains:annotations:19.0.0" -const val `caller-finder` = "io.github.karlatemp:caller:1.0.1" +const val `caller-finder` = "io.github.karlatemp:caller:1.1.1" val ATTRIBUTE_MIRAI_TARGET_PLATFORM: Attribute = Attribute.of("mirai.target.platform", String::class.java) \ No newline at end of file From 5bf1a9755fb3bf440a5427cbf2bf8ae05b1beec6 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Tue, 16 Feb 2021 22:44:01 +0800 Subject: [PATCH 03/10] Improve PsiMethod.hasSignature; fix #294 --- .../ResourceNotClosedInspectionTestJava.java | 12 ++++++++++++ .../src/main/java/test/TestJavaPlugin.java | 16 +++++++++++++++- .../src/resolve/FunctionSignature.kt | 17 ++++++++--------- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/tools/intellij-plugin/run/projects/test-project/src/main/java/test/ResourceNotClosedInspectionTestJava.java b/tools/intellij-plugin/run/projects/test-project/src/main/java/test/ResourceNotClosedInspectionTestJava.java index 3034e5657..e216b120a 100644 --- a/tools/intellij-plugin/run/projects/test-project/src/main/java/test/ResourceNotClosedInspectionTestJava.java +++ b/tools/intellij-plugin/run/projects/test-project/src/main/java/test/ResourceNotClosedInspectionTestJava.java @@ -11,7 +11,19 @@ import java.io.IOException; import static org.example.myplugin.ResourceNotClosedInspectionTestKt.magic; public class ResourceNotClosedInspectionTestJava { + + public static Object funA() { + return new Object(); + } + + public static void funB(Object obj) { + System.out.println(obj); + } + public static void main(String[] args) { + // https://github.com/mamoe/mirai-console/issues/294 + funB(funA()); + File file = magic(); Contact contact = magic(); diff --git a/tools/intellij-plugin/run/projects/test-project/src/main/java/test/TestJavaPlugin.java b/tools/intellij-plugin/run/projects/test-project/src/main/java/test/TestJavaPlugin.java index 2af0e12f8..28f9c3396 100644 --- a/tools/intellij-plugin/run/projects/test-project/src/main/java/test/TestJavaPlugin.java +++ b/tools/intellij-plugin/run/projects/test-project/src/main/java/test/TestJavaPlugin.java @@ -3,6 +3,7 @@ package test; import net.mamoe.mirai.console.command.Command; import net.mamoe.mirai.console.command.CommandOwner; import net.mamoe.mirai.console.command.descriptor.CommandSignatureFromKFunction; +import net.mamoe.mirai.console.command.java.JCompositeCommand; import net.mamoe.mirai.console.command.java.JSimpleCommand; import net.mamoe.mirai.console.permission.Permission; import net.mamoe.mirai.console.plugin.jvm.JavaPlugin; @@ -27,4 +28,17 @@ class TestCommand extends JSimpleCommand { public void test(String s) { } -} \ No newline at end of file +} + +class TestCommand2 extends JCompositeCommand { + public TestCommand2(@NotNull CommandOwner owner, @NotNull String primaryName, @NotNull String[] secondaryNames, @NotNull Permission parentPermission) { + super(owner, primaryName, secondaryNames, parentPermission); + } + + @SubCommand("test") + public void test() {} + + @SubCommand({}) + public void subCmd() { + } +} diff --git a/tools/intellij-plugin/src/resolve/FunctionSignature.kt b/tools/intellij-plugin/src/resolve/FunctionSignature.kt index 50b244aea..eb185fd79 100644 --- a/tools/intellij-plugin/src/resolve/FunctionSignature.kt +++ b/tools/intellij-plugin/src/resolve/FunctionSignature.kt @@ -96,16 +96,21 @@ fun KtFunction.hasSignature(functionSignature: FunctionSignature): Boolean { return true } -fun KtLightMethod.hasSignature(functionSignature: FunctionSignature): Boolean { + +fun PsiMethod.hasSignature(functionSignature: FunctionSignature): Boolean { if (functionSignature.name != null) { if (this.name != functionSignature.name) return false } val parameters = parameterList.parameters.toMutableList() if (functionSignature.dispatchReceiver != null) { - val kotlinContainingClassFqn = + val containingClass = this.containingClass ?: return false + + val kotlinContainingClassFqn = if (this is KtLightMethod) { if (this.modifierList.hasExplicitModifier(PsiModifier.STATIC)) { this.containingClass.kotlinOrigin?.companionObjects?.firstOrNull()?.fqName - } else this.containingClass.getKotlinFqName() + } else containingClass.getKotlinFqName() + } else containingClass.getKotlinFqName() + if (kotlinContainingClassFqn != functionSignature.dispatchReceiver) return false } if (functionSignature.extensionReceiver != null) { @@ -121,12 +126,6 @@ fun KtLightMethod.hasSignature(functionSignature: FunctionSignature): Boolean { return true } -fun PsiMethod.hasSignature(functionSignature: FunctionSignature): Boolean { - if (this is KtLightMethod) { - return this.hasSignature(functionSignature) - } - return true -} fun KtExpression.isCalling(functionSignature: FunctionSignature): Boolean { val descriptor = resolveToCall(BodyResolveMode.PARTIAL)?.resultingDescriptor ?: return false From 78e8203abde47d0e6dc3ecea38c608c94c001491 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Tue, 16 Feb 2021 23:13:27 +0800 Subject: [PATCH 04/10] Add default value of CompositeCommand.SubCommand.value for Java --- backend/mirai-console/src/command/CompositeCommand.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/mirai-console/src/command/CompositeCommand.kt b/backend/mirai-console/src/command/CompositeCommand.kt index ccb8d73fd..305cbd65b 100644 --- a/backend/mirai-console/src/command/CompositeCommand.kt +++ b/backend/mirai-console/src/command/CompositeCommand.kt @@ -121,7 +121,7 @@ public abstract class CompositeCommand( @Retention(RUNTIME) @Target(FUNCTION) protected annotation class SubCommand( - @ResolveContext(COMMAND_NAME) vararg val value: String, + @ResolveContext(COMMAND_NAME) vararg val value: String = [], ) /** 指令描述 */ From bc009263b5f13ac3587a9f379d1fd0ef17dc4b8e Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Wed, 17 Feb 2021 15:15:05 +0800 Subject: [PATCH 05/10] [Command] Support detect receiver parameter with first parameter; fix #295 --- .../src/internal/command/CommandReflector.kt | 21 +++++++++--- .../mirai-console/test/command/TestCommand.kt | 32 +++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/backend/mirai-console/src/internal/command/CommandReflector.kt b/backend/mirai-console/src/internal/command/CommandReflector.kt index 29015046f..37eaa1633 100644 --- a/backend/mirai-console/src/internal/command/CommandReflector.kt +++ b/backend/mirai-console/src/internal/command/CommandReflector.kt @@ -203,10 +203,12 @@ internal class CommandReflector( ) fun CommandParameter<*>.toErasedParameterInfo(index: Int): ErasedParameterInfo { - return ErasedParameterInfo(index, + return ErasedParameterInfo( + index, this.name, this.type.withNullability(false), - if (this is AbstractCommandValueParameter.StringConstant) this.expectingValue else null) + if (this is AbstractCommandValueParameter.StringConstant) this.expectingValue else null + ) } val candidates = signatures.map { variant -> @@ -244,11 +246,21 @@ internal class CommandReflector( name?.split(' ')?.mapIndexed { index, s -> createStringConstantParameterForName(index, s) } .orEmpty() + val valueParameters = function.valueParameters.toMutableList() + var receiverParameter = function.extensionReceiverParameter + if (receiverParameter == null && valueParameters.isNotEmpty()) { + val valueFirstParameter = valueParameters[0] + if (valueFirstParameter.type.classifierAsKClassOrNull()?.isSubclassOf(CommandSender::class) == true) { + receiverParameter = valueFirstParameter + valueParameters.removeAt(0) + } + } + val functionValueParameters = - function.valueParameters.associateBy { it.toUserDefinedCommandParameter() } + valueParameters.associateBy { it.toUserDefinedCommandParameter() } CommandSignatureFromKFunctionImpl( - receiverParameter = function.extensionReceiverParameter?.toCommandReceiverParameter(), + receiverParameter = receiverParameter?.toCommandReceiverParameter(), valueParameters = functionNameAsValueParameter + functionValueParameters.keys, originFunction = function ) { call -> @@ -272,7 +284,6 @@ internal class CommandReflector( args[instanceParameter] = command } - val receiverParameter = function.extensionReceiverParameter if (receiverParameter != null) { check(receiverParameter.type.classifierAsKClass().isInstance(call.caller)) { "Bad command call resolved. " + diff --git a/backend/mirai-console/test/command/TestCommand.kt b/backend/mirai-console/test/command/TestCommand.kt index f00898787..beee000aa 100644 --- a/backend/mirai-console/test/command/TestCommand.kt +++ b/backend/mirai-console/test/command/TestCommand.kt @@ -69,9 +69,11 @@ object TestEnumArgCommand : CompositeCommand(owner, "testenum") { enum class TestEnum { V1, V2, V3 } + enum class TestCase { A, a } + enum class TestCamelCase { A, B, A_B } @@ -295,6 +297,36 @@ internal class TestCommand { } } + @Test + fun `test first param command sender`() = runBlocking { + object : CompositeCommand(owner, "cmd") { + @SubCommand + fun handle(sender: CommandSender, arg: String) { + Testing.ok(arg) + } + }.withRegistration { + assertEquals("test", withTesting { assertSuccess(execute(sender, "handle test")) }) + } + + object : SimpleCommand(owner, "cmd") { + @Handler + fun handle(sender: CommandSender, arg: String) { + Testing.ok(arg) + } + }.withRegistration { + assertEquals("hello", withTesting { assertSuccess(execute(sender, "hello")) }) + } + + object : SimpleCommand(owner, "cmd") { + @Handler + fun handle(arg: String, sender: CommandSender) { + Testing.ok(arg) + } + }.withRegistration { + assertFailure(execute(sender, "hello")) + } + } + @Test fun `composite sub command resolution conflict`() { runBlocking { From 11e7d9f4549f27e329ec5009a90de11451b447df Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Thu, 18 Feb 2021 01:09:28 +0800 Subject: [PATCH 06/10] FrontEnd callbacks; Accessors for FrontEnd --- .../src/MiraiConsoleImplementation.kt | 39 +++++++++++++++ .../MiraiConsoleImplementationBridge.kt | 48 +++++++++++++------ 2 files changed, 72 insertions(+), 15 deletions(-) diff --git a/backend/mirai-console/src/MiraiConsoleImplementation.kt b/backend/mirai-console/src/MiraiConsoleImplementation.kt index 443d66551..428ca1b97 100644 --- a/backend/mirai-console/src/MiraiConsoleImplementation.kt +++ b/backend/mirai-console/src/MiraiConsoleImplementation.kt @@ -17,9 +17,13 @@ import net.mamoe.mirai.Bot import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.data.PluginDataStorage +import net.mamoe.mirai.console.extension.ComponentStorage import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge +import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl +import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl import net.mamoe.mirai.console.logging.LoggerController +import net.mamoe.mirai.console.plugin.Plugin import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader import net.mamoe.mirai.console.plugin.loader.PluginLoader import net.mamoe.mirai.console.util.ConsoleInput @@ -185,7 +189,42 @@ public interface MiraiConsoleImplementation : CoroutineScope { public val loggerController: LoggerController get() = LoggerControllerImpl + /// Hooks & Backend Access + /** + * 后端 在 [phase] 阶段执行前会调用此方法, 如果此方法抛出了一个错误会直接中断 console 初始化 + */ + public fun prePhase(phase: String) {} + + /** + * 后端 在 [phase] 阶段执行后会调用此方法, 如果此方法抛出了一个错误会直接中断 console 初始化 + */ + public fun postPhase(phase: String) {} + + /** 后端在 [start] 前会调用此方法 */ + public fun preStart() {} + + /** 后端在 [start] 后会调用此方法 */ + public fun postStart() {} + + /** + * 用于提供前端访问后端内部实现 + */ + @ConsoleFrontEndImplementation + public interface BackendAccess { + // GlobalComponentStorage + public val globalComponentStorage: ComponentStorage + // PluginManagerImpl.resolvedPlugins + public val resolvedPlugins: MutableList + } + + public val backendAccess: BackendAccess get() = backendAccessInstance + public companion object { + private val backendAccessInstance = object : BackendAccess { + override val globalComponentStorage: ComponentStorage get() = GlobalComponentStorage + override val resolvedPlugins: MutableList get() = PluginManagerImpl.resolvedPlugins + } + internal lateinit var instance: MiraiConsoleImplementation private val initLock = ReentrantLock() diff --git a/backend/mirai-console/src/internal/MiraiConsoleImplementationBridge.kt b/backend/mirai-console/src/internal/MiraiConsoleImplementationBridge.kt index 8658ea516..2bdb53b0c 100644 --- a/backend/mirai-console/src/internal/MiraiConsoleImplementationBridge.kt +++ b/backend/mirai-console/src/internal/MiraiConsoleImplementationBridge.kt @@ -16,7 +16,10 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.runBlocking import net.mamoe.mirai.Bot -import net.mamoe.mirai.console.* +import net.mamoe.mirai.console.MalformedMiraiConsoleImplementationError +import net.mamoe.mirai.console.MiraiConsole +import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription +import net.mamoe.mirai.console.MiraiConsoleImplementation import net.mamoe.mirai.console.command.BuiltInCommands import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.command.ConsoleCommandSender @@ -104,8 +107,9 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI @Suppress("RemoveRedundantBackticks") internal fun doStart() { + instance.preStart() - phase `setup logger controller`@{ + phase("setup logger controller") { if (loggerController === LoggerControllerImpl) { // Reload LoggerConfig. ConsoleDataScope.addAndReloadConfig(LoggerConfig) @@ -113,7 +117,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI } } - phase `greeting`@{ + phase("greeting") { val buildDateFormatted = buildDate.atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) @@ -122,7 +126,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI mainLogger.info { frontEndDescription.render() } } - phase `check coroutineContext`@{ + phase("check coroutineContext") { if (coroutineContext[Job] == null) { throw MalformedMiraiConsoleImplementationError("The coroutineContext given to MiraiConsole must have a Job in it.") } @@ -139,13 +143,13 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI // start - phase `load configurations`@{ + phase("load configurations") { mainLogger.verbose { "Loading configurations..." } ConsoleDataScope.addAndReloadConfig(CommandConfig) ConsoleDataScope.reloadAll() } - phase `initialize all plugins`@{ + phase("initialize all plugins") { PluginManager // init mainLogger.verbose { "Loading JVM plugins..." } @@ -158,13 +162,13 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI } } - phase `load all plugins`@{ + phase("load all plugins") { PluginManagerImpl.loadPlugins(PluginManagerImpl.scanPluginsUsingPluginLoadersIncludingThoseFromPluginLoaderProvider()) mainLogger.verbose { "${PluginManager.plugins.size} plugin(s) loaded." } } - phase `load SingletonExtensionSelector`@{ + phase("load SingletonExtensionSelector") { SingletonExtensionSelector.init() val instance = SingletonExtensionSelector.instance if (instance is BuiltInSingletonExtensionSelector) { @@ -173,7 +177,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI } - phase `load PermissionService`@{ + phase("load PermissionService") { mainLogger.verbose { "Loading PermissionService..." } PermissionService.INSTANCE.let { ps -> @@ -188,7 +192,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI runIgnoreException { ConsoleCommandSender.permit(RootPermission) } } - phase `prepare commands`@{ + phase("prepare commands") { mainLogger.verbose { "Loading built-in commands..." } BuiltInCommands.registerAll() mainLogger.info { "Prepared built-in commands: ${BuiltInCommands.all.joinToString { it.primaryName }}" } @@ -196,7 +200,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI // CommandManagerImpl.commandListener // start } - phase `enable plugins`@{ + phase("enable plugins") { mainLogger.verbose { "Enabling plugins..." } PluginManagerImpl.enableAllLoadedPlugins() @@ -208,7 +212,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI mainLogger.info { "${PluginManagerImpl.plugins.size} plugin(s) enabled." } } - phase `auto-login bots`@{ + phase("auto-login bots") { runBlocking { val accounts = AutoLoginConfig.accounts.toList() for (account in accounts) { @@ -259,10 +263,14 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI } } - GlobalComponentStorage.run { - PostStartupExtension.useExtensions { it() } // exceptions thrown will be caught by caller of `doStart`. + phase("finally post") { + GlobalComponentStorage.run { + PostStartupExtension.useExtensions { it() } // exceptions thrown will be caught by caller of `doStart`. + } } + instance.postStart() + mainLogger.info { "mirai-console started successfully." } } @@ -275,10 +283,20 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI * 表示一个初始化阶段, 无实际作用. */ @ILoveOmaeKumikoForever - private inline fun phase(block: () -> Unit) { + private inline fun phase(phase: String, block: () -> Unit) { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + prePhase(phase) block() + postPhase(phase) + } + + override fun prePhase(phase: String) { + instance.prePhase(phase) + } + + override fun postPhase(phase: String) { + instance.postPhase(phase) } } \ No newline at end of file From 7c863e935331b3c6b50bc6c8dfb30ce27a163b82 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Thu, 18 Feb 2021 01:13:06 +0800 Subject: [PATCH 07/10] Limit MiraiConsoleImplementation.backendAccess --- .../mirai-console/src/MiraiConsoleImplementation.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/backend/mirai-console/src/MiraiConsoleImplementation.kt b/backend/mirai-console/src/MiraiConsoleImplementation.kt index 428ca1b97..da85d7ddd 100644 --- a/backend/mirai-console/src/MiraiConsoleImplementation.kt +++ b/backend/mirai-console/src/MiraiConsoleImplementation.kt @@ -31,6 +31,7 @@ import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.LoginSolver import net.mamoe.mirai.utils.MiraiLogger +import java.lang.IllegalStateException import java.nio.file.Path import java.util.* import java.util.concurrent.locks.ReentrantLock @@ -217,7 +218,13 @@ public interface MiraiConsoleImplementation : CoroutineScope { public val resolvedPlugins: MutableList } - public val backendAccess: BackendAccess get() = backendAccessInstance + public val backendAccess: BackendAccess get() { + if (instanceInitialized) { + if (this === instance) + return backendAccessInstance + } + throw IllegalStateException("Permission denied") + } public companion object { private val backendAccessInstance = object : BackendAccess { @@ -226,6 +233,7 @@ public interface MiraiConsoleImplementation : CoroutineScope { } internal lateinit var instance: MiraiConsoleImplementation + internal val instanceInitialized: Boolean get() = ::instance.isInitialized private val initLock = ReentrantLock() /** From 825332abfefd498092c31ae57e5e27fd0e996339 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Thu, 18 Feb 2021 01:22:56 +0800 Subject: [PATCH 08/10] Update comments --- .../src/MiraiConsoleImplementation.kt | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/backend/mirai-console/src/MiraiConsoleImplementation.kt b/backend/mirai-console/src/MiraiConsoleImplementation.kt index da85d7ddd..7a2417b56 100644 --- a/backend/mirai-console/src/MiraiConsoleImplementation.kt +++ b/backend/mirai-console/src/MiraiConsoleImplementation.kt @@ -31,7 +31,6 @@ import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.LoginSolver import net.mamoe.mirai.utils.MiraiLogger -import java.lang.IllegalStateException import java.nio.file.Path import java.util.* import java.util.concurrent.locks.ReentrantLock @@ -193,38 +192,60 @@ public interface MiraiConsoleImplementation : CoroutineScope { /// Hooks & Backend Access /** * 后端 在 [phase] 阶段执行前会调用此方法, 如果此方法抛出了一个错误会直接中断 console 初始化 + * + * @since 2.5.0-dev-2 */ public fun prePhase(phase: String) {} /** * 后端 在 [phase] 阶段执行后会调用此方法, 如果此方法抛出了一个错误会直接中断 console 初始化 + * + * @since 2.5.0-dev-2 */ public fun postPhase(phase: String) {} - /** 后端在 [start] 前会调用此方法 */ + /** + * 后端在 [start] 前会调用此方法 + * + * @since 2.5.0-dev-2 + */ public fun preStart() {} - /** 后端在 [start] 后会调用此方法 */ + /** + * 后端在 [start] 后会调用此方法 + * + * @since 2.5.0-dev-2 + */ public fun postStart() {} /** - * 用于提供前端访问后端内部实现 + * 前端访问后端内部实现的桥 + * + * @see backendAccess + * @since 2.5.0-dev-2 */ @ConsoleFrontEndImplementation public interface BackendAccess { // GlobalComponentStorage public val globalComponentStorage: ComponentStorage + // PluginManagerImpl.resolvedPlugins public val resolvedPlugins: MutableList } - public val backendAccess: BackendAccess get() { - if (instanceInitialized) { - if (this === instance) - return backendAccessInstance + /** + * @see BackendAccess + * @since 2.5.0-dev-2 + * @throws IllegalStateException 当前端实例不是 `this` 时抛出 + */ + public val backendAccess: BackendAccess + get() { + if (instanceInitialized) { + if (this === instance) + return backendAccessInstance + } + throw IllegalStateException("Permission denied") } - throw IllegalStateException("Permission denied") - } public companion object { private val backendAccessInstance = object : BackendAccess { From 0fa67b7699bc83767b396e8cde9b640acbe3e893 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Thu, 18 Feb 2021 12:06:56 +0800 Subject: [PATCH 09/10] Improve service finding - Close resource stream - Skip comments --- .../src/internal/util/PluginServiceHelper.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/backend/mirai-console/src/internal/util/PluginServiceHelper.kt b/backend/mirai-console/src/internal/util/PluginServiceHelper.kt index 86dc84dab..c65e16135 100644 --- a/backend/mirai-console/src/internal/util/PluginServiceHelper.kt +++ b/backend/mirai-console/src/internal/util/PluginServiceHelper.kt @@ -14,7 +14,6 @@ package net.mamoe.mirai.console.internal.util import net.mamoe.mirai.console.internal.data.cast import net.mamoe.mirai.console.internal.data.createInstanceOrNull import net.mamoe.mirai.console.internal.plugin.BuiltInJvmPluginLoaderImpl -import java.io.InputStream import java.lang.reflect.Modifier import java.util.* import kotlin.reflect.KClass @@ -30,9 +29,13 @@ internal object PluginServiceHelper { fun ClassLoader.findServices(vararg serviceTypes: KClass): ServiceList = serviceTypes.flatMap { serviceType -> - getResourceAsStream("META-INF/services/" + serviceType.qualifiedName!!) - ?.use(InputStream::readBytes) - ?.let(::String)?.lines()?.filter(String::isNotBlank).orEmpty() + getResourceAsStream("META-INF/services/" + serviceType.qualifiedName!!)?.let { stream -> + stream.bufferedReader().useLines { lines -> + lines.filter(String::isNotBlank) + .filter { it[0] != '#' } + .toList() + } + }.orEmpty() }.let { ServiceList(this, it) } fun ServiceList.loadAllServices(): List { From 2e286a3a79213d12a4763f6e124fd5cf6ebe6d54 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 20 Feb 2021 19:51:23 +0800 Subject: [PATCH 10/10] Don't show not permitted commands in `/help` --- backend/mirai-console/src/command/BuiltInCommands.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/mirai-console/src/command/BuiltInCommands.kt b/backend/mirai-console/src/command/BuiltInCommands.kt index a5d15c74f..e16d16242 100644 --- a/backend/mirai-console/src/command/BuiltInCommands.kt +++ b/backend/mirai-console/src/command/BuiltInCommands.kt @@ -37,6 +37,7 @@ import net.mamoe.mirai.console.permission.PermissionService import net.mamoe.mirai.console.permission.PermissionService.Companion.cancel import net.mamoe.mirai.console.permission.PermissionService.Companion.findCorrespondingPermissionOrFail import net.mamoe.mirai.console.permission.PermissionService.Companion.getPermittedPermissions +import net.mamoe.mirai.console.permission.PermissionService.Companion.hasPermission import net.mamoe.mirai.console.permission.PermissionService.Companion.permit import net.mamoe.mirai.console.permission.PermitteeId import net.mamoe.mirai.console.plugin.name @@ -98,6 +99,7 @@ public object BuiltInCommands { public suspend fun CommandSender.handle() { sendMessage( allRegisteredCommands + .filter { hasPermission(it.permission) } .joinToString("\n\n") { command -> val lines = command.usage.lines() if (lines.isEmpty()) "/${command.primaryName} ${command.description}"