Merge remote-tracking branch 'origin/reborn' into reborn

# Conflicts:
#	backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt
This commit is contained in:
jiahua.liu 2020-05-26 17:02:06 +08:00
commit b66142545c
31 changed files with 887 additions and 350 deletions

View File

@ -3,10 +3,10 @@ package net.mamoe.n;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.mamoe.mirai.console.command.*;
import net.mamoe.mirai.console.plugins.Config;
import net.mamoe.mirai.console.plugins.ConfigSection;
import net.mamoe.mirai.console.plugins.ConfigSectionFactory;
import net.mamoe.mirai.console.plugins.PluginBase;
import net.mamoe.mirai.console.plugin.Config;
import net.mamoe.mirai.console.plugin.ConfigSection;
import net.mamoe.mirai.console.plugin.ConfigSectionFactory;
import net.mamoe.mirai.console.plugin.PluginBase;
import net.mamoe.mirai.console.utils.Utils;
import net.mamoe.mirai.message.GroupMessage;
import org.jetbrains.annotations.NotNull;

View File

@ -101,7 +101,11 @@ fun genAllValueUseSite(): String = buildString {
require(this::class != default::class) {
"Recursive nesting is prohibited"
}
return valueImpl(default)
return valueImpl(default).also {
if (default is Setting.NestedSetting) {
default.attachedValue = it
}
}
}
inline fun <T : Setting> Setting.value(default: T, crossinline initializer: T.() -> Unit): Value<T> =

View File

@ -110,7 +110,7 @@ fun genAllValueImpl(): String = buildString {
): Mutable${number}${collectionName}Value {
var internalValue: Mutable${collectionName}<${number}> = default
val delegt = dynamicMutable${collectionName}{ internalValue }
val delegt = dynamicMutable${collectionName} { internalValue }
return object : Mutable${number}${collectionName}Value(), Mutable${collectionName}<${number}> by delegt {
override var value: Mutable${collectionName}<${number}>
get() = internalValue
@ -125,7 +125,7 @@ fun genAllValueImpl(): String = buildString {
override val serializer: KSerializer<Mutable${collectionName}<${number}>> = object : KSerializer<Mutable${collectionName}<${number}>> {
private val delegate = ${collectionName}Serializer(${number}.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): Mutable${collectionName}<${number}> {
return delegate.deserialize(decoder).toMutable${collectionName}().observable {
@ -208,7 +208,7 @@ fun genPrimitiveValueImpl(
""".trim()
}
}
override val serializer = $serializer
override val serializer get() = $serializer
}
}
""".trimIndent() + "\n"
@ -244,7 +244,7 @@ fun genCollectionValueImpl(
""".trim()
}
}
override val serializer = $serializer
override val serializer get() = $serializer
}
}
""".trimIndent() + "\n"

View File

@ -0,0 +1,139 @@
package net.mamoe.mirai.console.command;
import kotlin.NotImplementedError;
import kotlin.coroutines.EmptyCoroutineContext;
import kotlinx.coroutines.BuildersKt;
import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.CoroutineStart;
import kotlinx.coroutines.future.FutureKt;
import net.mamoe.mirai.console.plugin.jvm.JavaPlugin;
import net.mamoe.mirai.message.data.Message;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
/**
* Java 适配的 {@link CommandManagerKt}
*/
@SuppressWarnings("unused")
public final class JCommandManager {
private JCommandManager() {
throw new NotImplementedError();
}
/**
* 获取指令前缀
*
* @return 指令前缀
*/
@NotNull
public static String getCommandPrefix() {
return CommandManagerKt.getCommandPrefix();
}
/**
* 获取一个指令所有者已经注册了的指令列表.
*
* @param owner 指令所有者
* @return 指令列表
*/
@NotNull
public static List<@NotNull Command> getRegisteredCommands(final @NotNull CommandOwner owner) {
return CommandManagerKt.getRegisteredCommands(Objects.requireNonNull(owner, "owner"));
}
/**
* 注册一个指令.
*
* @param command 指令实例
* @param override 是否覆盖重名指令.
* <p>
* 若原有指令 P, {@link Command#getNames()} 'a', 'b', 'c'. <br>
* 新指令 Q, {@link Command#getNames()} 'b', 将会覆盖原指令 A 注册的 'b'.
* <p>
* 即注册完成后, 'a' 'c' 将会解析到指令 P, 'b' 会解析到指令 Q.
* @return 若已有重名指令, <code>override</code> <code>false</code>, 返回 <code>false</code>; <br>
* 若已有重名指令, <code>override</code> <code>true</code>, 覆盖原有指令并返回 <code>true</code>.
*/
public static boolean register(final @NotNull Command command, final boolean override) {
Objects.requireNonNull(command, "command");
return CommandManagerKt.register(command, override);
}
/**
* 注册一个指令, 已有重复名称的指令时返回 <code>false</code>
*
* @param command 指令实例
* @return 若已有重名指令, 返回 <code>false</code>, 否则返回 <code>true</code>.
*/
public static boolean register(final @NotNull Command command) {
Objects.requireNonNull(command, "command");
return register(command, false);
}
/**
* 查找并返回重名的指令. 返回重名指令.
*/
@Nullable
public static Command findDuplicate(final @NotNull Command command) {
Objects.requireNonNull(command, "command");
return CommandManagerKt.findDuplicate(command);
}
/**
* 取消注册这个指令. 若指令未注册, 返回 <code>false</code>.
*/
public static boolean unregister(final @NotNull Command command) {
Objects.requireNonNull(command, "command");
return CommandManagerKt.unregister(command);
}
/**
* 取消注册所有属于 <code>owner</code> 的指令
*
* @param owner 指令所有者
*/
public static void unregisterAllCommands(final @NotNull CommandOwner owner) {
Objects.requireNonNull(owner, "owner");
CommandManagerKt.unregisterAllCommands(owner);
}
/**
* 解析并执行一个指令
*
* @param args 接受 {@link String} {@link Message} , 其他对象将会被 {@link Object#toString()}
* @return 是否成功解析到指令. 返回 `false` 代表无任何指令匹配
* @see #executeCommandAsync(CoroutineScope, CommandSender, Object...)
*/
public static boolean executeCommand(final @NotNull CommandSender sender, final @NotNull Object... args) throws InterruptedException {
Objects.requireNonNull(sender, "sender");
Objects.requireNonNull(args, "args");
for (Object arg : args) {
Objects.requireNonNull(arg, "element of args");
}
return BuildersKt.runBlocking(EmptyCoroutineContext.INSTANCE, (scope, completion) -> CommandManagerKt.executeCommand(sender, args, completion));
}
/**
* 异步 ( Kotlin 协程线程池) 解析并执行一个指令
*
* @param scope 协程作用域 (用于管理协程生命周期). 一般填入 {@link JavaPlugin} 实例.
* @param args 接受 {@link String} {@link Message} , 其他对象将会被 {@link Object#toString()}
* @return 是否成功解析到指令. 返回 `false` 代表无任何指令匹配
* @see #executeCommand(CommandSender, Object...)
*/
public static CompletableFuture<Boolean> executeCommandAsync(final @NotNull CoroutineScope scope, final @NotNull CommandSender sender, final @NotNull Object... args) {
Objects.requireNonNull(sender, "sender");
Objects.requireNonNull(args, "args");
Objects.requireNonNull(scope, "scope");
for (Object arg : args) {
Objects.requireNonNull(arg, "element of args");
}
return FutureKt.future(scope, EmptyCoroutineContext.INSTANCE, CoroutineStart.DEFAULT, (sc, completion) -> CommandManagerKt.executeCommand(sender, args, completion));
}
}

View File

@ -25,7 +25,7 @@ public class BotManager {
}
public static List<Long> getManagers(Bot bot) {
return BotHelperKt.getBotManagers(bot);
return BotManagers.getManagers(bot);
}
public static boolean isManager(Bot bot, long target) {

View File

@ -13,8 +13,11 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.io.charsets.Charset
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.plugins.PluginLoader
import net.mamoe.mirai.console.plugins.builtin.JarPluginLoader
import net.mamoe.mirai.console.plugin.PluginLoader
import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import net.mamoe.mirai.console.setting.SettingStorage
import net.mamoe.mirai.console.setting.internal.ConsoleBuiltInSetting
import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.MiraiLogger
@ -34,14 +37,48 @@ object MiraiConsole : CoroutineScope, IMiraiConsole {
this.instance = instance
}
override val build: String get() = instance.build
override val version: String get() = instance.version
/**
* `mirai-console` build
*/
@MiraiExperimentalAPI
override val build: String
get() = instance.build
/**
* `mirai-console` 版本
*/
@MiraiExperimentalAPI
override val version: String
get() = instance.version
/**
* Console 运行路径
*/
override val rootDir: File get() = instance.rootDir
/**
* Console 前端接口
*/
override val frontEnd: MiraiConsoleFrontEnd get() = instance.frontEnd
override val mainLogger: MiraiLogger get() = instance.mainLogger
/**
* 与前端交互所使用的 Logger
*/
@MiraiExperimentalAPI
override val mainLogger: MiraiLogger
get() = instance.mainLogger
override val coroutineContext: CoroutineContext get() = instance.coroutineContext
override val builtInPluginLoaders: List<PluginLoader<*, *>> = instance.builtInPluginLoaders
override val builtInPluginLoaders: List<PluginLoader<*, *>> get() = instance.builtInPluginLoaders
@Suppress("CANNOT_WEAKEN_ACCESS_PRIVILEGE")
internal override val jvmSettingStorage: SettingStorage
get() = instance.jvmSettingStorage
@Suppress("CANNOT_WEAKEN_ACCESS_PRIVILEGE")
override val consoleBuiltIntSettingStorage: SettingStorage
get() = instance.consoleBuiltIntSettingStorage
init {
DefaultLogger = { identity -> this.newLogger(identity) }
@ -79,6 +116,16 @@ internal interface IMiraiConsole : CoroutineScope {
* 内建加载器列表, 一般需要包含 [JarPluginLoader]
*/
val builtInPluginLoaders: List<PluginLoader<*, *>>
/**
* 内建的供 [JvmPlugin] 使用的 [SettingStorage]
*/
val jvmSettingStorage: SettingStorage
/**
* 内建的供 [ConsoleBuiltInSetting] 使用的 [SettingStorage]
*/
val consoleBuiltIntSettingStorage: SettingStorage
}
/**

View File

@ -12,13 +12,8 @@
package net.mamoe.mirai.console.command
import net.mamoe.mirai.console.command.description.*
import net.mamoe.mirai.console.command.description.CommandParam
import net.mamoe.mirai.console.command.description.CommandParserContext
import net.mamoe.mirai.console.command.description.EmptyCommandParserContext
import net.mamoe.mirai.console.command.description.plus
import net.mamoe.mirai.message.data.PlainText
import net.mamoe.mirai.message.data.SingleMessage
import java.lang.Exception
import kotlin.reflect.KAnnotatedElement
import kotlin.reflect.KClass
import kotlin.reflect.full.*
@ -29,20 +24,37 @@ import kotlin.reflect.full.*
* @see register 注册这个指令
*/
interface Command {
/**
* 指令名. 需要至少有一个元素. 所有元素都不能带有空格
*/
val names: Array<out String>
fun getPrimaryName():String = names[0]
val usage: String
val description: String
/**
* 指令权限
*/
val permission: CommandPermission
/**
* `true` 时表示 [指令前缀][CommandPrefix] 可选
*/
val prefixOptional: Boolean
val owner: CommandOwner
/**
* @param args 指令参数. 可能是 [SingleMessage] [String]. 且已经以 ' ' 分割.
*/
suspend fun onCommand(sender: CommandSender, args: Array<out Any>)
}
/**
* 主要指令名. [Command.names] 的第一个元素.
*/
val Command.primaryName: String get() = names[0]
/**
* 功能最集中的Commend
* 支持且只支持有sub的指令
@ -55,20 +67,26 @@ interface Command {
abstract class CompositeCommand @JvmOverloads constructor(
override val owner: CommandOwner,
vararg names: String,
override val description: String = "no description available",
description: String = "no description available",
override val permission: CommandPermission = CommandPermission.Default,
override val prefixOptional: Boolean = false,
overrideContext: CommandParserContext = EmptyCommandParserContext
) : Command {
class IllegalParameterException(message:String): Exception(message)
override val description = description.trimIndent()
override val names: Array<out String> =
names.map(String::trim).filterNot(String::isEmpty).map(String::toLowerCase).toTypedArray()
names.map(String::trim).filterNot(String::isEmpty).map(String::toLowerCase).also { list ->
list.firstOrNull { !it.isValidSubName() }?.let {
error("Name is not valid: $it")
}
}.toTypedArray()
/**
* [CommandArgParser] 的环境
*/
val context: CommandParserContext = CommandParserContext.Builtins + overrideContext
override lateinit var usage: String
override var usage: String = "<command build failed>" // initialized by subCommand reflection
internal set
/** 指定子指令要求的权限 */
@Retention(AnnotationRetention.RUNTIME)
@ -107,6 +125,9 @@ abstract class CompositeCommand @JvmOverloads constructor(
)
}
class IllegalParameterException internal constructor(message: String) : Exception(message)
internal val subCommands: Array<SubCommandDescriptor> by lazy {
val buildUsage = StringBuilder(this.description).append(": \n")
@ -117,7 +138,7 @@ abstract class CompositeCommand @JvmOverloads constructor(
val overridePermission = function.findAnnotation<Permission>()//optional
val subDescription = function.findAnnotation<Description>()?.description?:"no description available"
if((function.returnType.classifier as? KClass<*>)?.isSubclassOf(Boolean::class) != true){
if ((function.returnType.classifier as? KClass<*>)?.isSubclassOf(Boolean::class) != true) {
throw IllegalParameterException("Return Type of SubCommand must be Boolean")
}
@ -126,7 +147,7 @@ abstract class CompositeCommand @JvmOverloads constructor(
throw IllegalParameterException("First parameter (receiver for kotlin) for sub commend " + function.name + " from " + this.getPrimaryName() + " should be <out CommandSender>")
}
if(notStatic){
if (notStatic) {
parameter.removeAt(0)
}
@ -136,12 +157,12 @@ abstract class CompositeCommand @JvmOverloads constructor(
((receiver.type.classifier as? KClass<*>).also { print(it) }
?.isSubclassOf(CommandSender::class) != true)
) {
throw IllegalParameterException("First parameter (receiver for kotlin) for sub commend " + function.name + " from " + this.getPrimaryName() + " should be <out CommandSender>")
throw IllegalParameterException("First parameter (receiver for kotlin) for sub commend " + function.name + " from " + this.primaryName + " should be <out CommandSender>")
}
}
val commandName = function.findAnnotation<SubCommand>()!!.name.map {
if(!it.isValidSubName()){
if (!it.isValidSubName()) {
error("SubName $it is not valid")
}
it
@ -149,20 +170,22 @@ abstract class CompositeCommand @JvmOverloads constructor(
//map parameter
val parms = parameter.map {
buildUsage.append("/" + getPrimaryName() + " ")
buildUsage.append("/$primaryName ")
if(it.isVararg){
throw IllegalParameterException("parameter for sub commend " + function.name + " from " + this.getPrimaryName() + " should not be var arg")
if (it.isVararg) {
throw IllegalParameterException("parameter for sub commend " + function.name + " from " + this.primaryName + " should not be var arg")
}
if(it.isOptional){
throw IllegalParameterException("parameter for sub commend " + function.name + " from " + this.getPrimaryName() + " should not be var optional")
if (it.isOptional) {
throw IllegalParameterException("parameter for sub commend " + function.name + " from " + this.primaryName + " should not be var optional")
}
val argName = it.findAnnotation<Name>()?.name?:it.name?:"unknown"
buildUsage.append("<").append(argName).append("> ")
val argName = it.findAnnotation<Name>()?.name ?: it.name ?: "unknown"
buildUsage.append("<").append(argName).append("> ").append(" ")
CommandParam(
argName,
(it.type.classifier as? KClass<*>)?: throw IllegalParameterException("unsolved type reference from param " + it.name + " in " + function.name + " from " + this.getPrimaryName()))
(it.type.classifier as? KClass<*>)
?: throw IllegalParameterException("unsolved type reference from param " + it.name + " in " + function.name + " from " + this.primaryName)
)
}.toTypedArray()
buildUsage.append(subDescription).append("\n")
@ -173,9 +196,9 @@ abstract class CompositeCommand @JvmOverloads constructor(
subDescription,
overridePermission?.permission?.getInstance() ?: permission,
onCommand = block { sender: CommandSender, args: Array<out Any> ->
if(notStatic) {
function.callSuspend(this,sender, *args) as Boolean
}else{
if (notStatic) {
function.callSuspend(this, sender, *args) as Boolean
} else {
function.callSuspend(sender, *args) as Boolean
}
}
@ -306,7 +329,7 @@ internal fun Any.flattenCommandComponents(): ArrayList<Any> {
internal inline fun <reified T : Annotation> KAnnotatedElement.hasAnnotation(): Boolean =
findAnnotation<T>() != null
internal inline fun <T:Any> KClass<out T>.getInstance():T {
internal inline fun <T : Any> KClass<out T>.getInstance(): T {
return this.objectInstance ?: this.createInstance()
}

View File

@ -8,34 +8,66 @@
*/
@file:Suppress("NOTHING_TO_INLINE", "unused")
@file:JvmName("CommandManager")
@file:JvmName("CommandManagerKt")
package net.mamoe.mirai.console.command
import kotlinx.atomicfu.locks.withLock
import net.mamoe.mirai.console.plugins.Plugin
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.SingleMessage
import net.mamoe.mirai.utils.MiraiInternalAPI
/**
* 指令的所有者.
* @see PluginCommandOwner
*/
sealed class CommandOwner
@MiraiInternalAPI
object TestCommandOwner : CommandOwner()
abstract class PluginCommandOwner(val plugin: Plugin) : CommandOwner()
/**
* 插件指令所有者. 插件只能通过 [PluginCommandOwner] 管理指令.
*/
abstract class PluginCommandOwner(val plugin: Plugin) : CommandOwner() {
init {
if (plugin is CoroutineScope) { // JVM Plugin
plugin.coroutineContext[Job]?.invokeOnCompletion {
this.unregisterAllCommands()
}
}
}
}
// 由前端实现
/**
* 代表控制台所有者. 所有的 mirai-console 内建的指令都属于 [ConsoleCommandOwner].
*
* 由前端实现
*/
internal abstract class ConsoleCommandOwner : CommandOwner()
/**
* 获取已经注册了的指令列表
* 获取已经注册了的属于这个 [CommandOwner] 的指令列表.
* @see JCommandManager.getRegisteredCommands Java 方法
*/
val CommandOwner.registeredCommands: List<Command> get() = InternalCommandManager.registeredCommands.filter { it.owner == this }
/**
* 指令前缀, '/'
* @see JCommandManager.getCommandPrefix Java 方法
*/
@get:JvmName("getCommandPrefix")
val CommandPrefix: String
get() = InternalCommandManager.COMMAND_PREFIX
/**
* 取消注册所有属于 [this] 的指令
* @see JCommandManager.unregisterAllCommands Java 方法
*/
fun CommandOwner.unregisterAllCommands() {
for (registeredCommand in registeredCommands) {
registeredCommand.unregister()
@ -43,10 +75,26 @@ fun CommandOwner.unregisterAllCommands() {
}
/**
* 注册一个指令. 若此指令已经注册或有已经注册的指令与 [SubCommandDescriptor] 重名, 返回 `false`
* 注册一个指令.
*
* @param override 是否覆盖重名指令.
*
* 若原有指令 P, [Command.names] 'a', 'b', 'c'.
* 新指令 Q, [Command.names] 'b', 将会覆盖原指令 A 注册的 'b'.
*
* 即注册完成后, 'a' 'c' 将会解析到指令 P, 'b' 会解析到指令 Q.
*
* @return
* 若已有重名指令, [override] `false`, 返回 `false`;
* 若已有重名指令, [override] `true`, 覆盖原有指令并返回 `true`.
*
* @see JCommandManager.register Java 方法
*/
fun Command.register(): Boolean = InternalCommandManager.modifyLock.withLock {
if (findDuplicate() != null) return false
@JvmOverloads
fun Command.register(override: Boolean = false): Boolean = InternalCommandManager.modifyLock.withLock {
if (!override) {
if (findDuplicate() != null) return false
}
InternalCommandManager.registeredCommands.add(this@register)
if (this.prefixOptional) {
for (name in this.names) {
@ -54,6 +102,7 @@ fun Command.register(): Boolean = InternalCommandManager.modifyLock.withLock {
}
} else {
for (name in this.names) {
InternalCommandManager.optionalPrefixCommandMap.remove(name) // ensure resolution consistency
InternalCommandManager.requiredPrefixCommandMap[name] = this
}
}
@ -61,13 +110,17 @@ fun Command.register(): Boolean = InternalCommandManager.modifyLock.withLock {
}
/**
* 查找是否有重名的指令. 返回重名的指令.
* 查找并返回重名的指令. 返回重名指令.
*
* @see JCommandManager.findDuplicate Java 方法
*/
fun Command.findDuplicate(): Command? =
InternalCommandManager.registeredCommands.firstOrNull { it.names intersects this.names }
/**
* 取消注册这个指令. 若指令未注册, 返回 `false`
* 取消注册这个指令. 若指令未注册, 返回 `false`.
*
* @see JCommandManager.unregister Java 方法
*/
fun Command.unregister(): Boolean = InternalCommandManager.modifyLock.withLock {
InternalCommandManager.registeredCommands.remove(this)
@ -78,8 +131,12 @@ fun Command.unregister(): Boolean = InternalCommandManager.modifyLock.withLock {
/**
* 解析并执行一个指令
*
* Java 调用方式: `<static> CommandManager.executeCommand(Command)`
*
* @param messages 接受 [String] [Message], 其他对象将会被 [Any.toString]
* @return 是否成功解析到指令. 返回 `false` 代表无任何指令匹配
*
* @see JCommandManager.executeCommand Java 方法
*/
suspend fun CommandSender.executeCommand(vararg messages: Any): Boolean {
if (messages.isEmpty()) return false
@ -88,17 +145,21 @@ suspend fun CommandSender.executeCommand(vararg messages: Any): Boolean {
messages[0].let { if (it is SingleMessage) it.toString() else it.toString().substringBefore(' ') })
}
@JvmSynthetic
internal inline fun <reified T> List<T>.dropToTypedArray(n: Int): Array<T> = Array(size - n) { this[n + it] }
/**
* 解析并执行一个指令
* @return 是否成功解析到指令. 返回 `false` 代表无任何指令匹配
*
* @see JCommandManager.executeCommand Java 方法
*/
suspend fun CommandSender.executeCommand(message: MessageChain): Boolean {
if (message.isEmpty()) return false
return executeCommandInternal(message, message[0].toString())
}
@JvmSynthetic
internal suspend inline fun CommandSender.executeCommandInternal(
messages: Any,
commandName: String

View File

@ -7,22 +7,26 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("NOTHING_TO_INLINE")
@file:Suppress("NOTHING_TO_INLINE", "INAPPLICABLE_JVM_NAME")
package net.mamoe.mirai.console.command
import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.utils.JavaFriendlyAPI
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.message.MessageEvent
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.PlainText
import org.jetbrains.annotations.Contract
/**
* 指令发送者
*
* @see AbstractCommandSender 请继承于该抽象类
*/
@Suppress("FunctionName")
interface CommandSender {
/**
* 与这个 [CommandSender] 相关的 [Bot]. 当通过控制台执行时为 null.
@ -32,15 +36,18 @@ interface CommandSender {
/**
* 立刻发送一条消息
*/
@JvmSynthetic
suspend fun sendMessage(message: Message)
/**
* 写入要发送的内容 所有内容最后会被以一条发出
*/
fun appendMessage(message: String)
@JvmDefault
@JavaFriendlyAPI
@JvmName("sendMessage")
fun __sendMessageBlocking(messageChain: Message) = runBlocking { sendMessage(messageChain) }
fun sendMessageBlocking(messageChain: Message) = runBlocking { sendMessage(messageChain) }
fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) }
@JvmDefault
@JavaFriendlyAPI
@JvmName("sendMessage")
fun __sendMessageBlocking(message: String) = runBlocking { sendMessage(message) }
}
/**
@ -52,42 +59,19 @@ interface BotAwareCommandSender : CommandSender {
suspend inline fun CommandSender.sendMessage(message: String) = sendMessage(PlainText(message))
abstract class AbstractCommandSender : CommandSender {
internal val builder = StringBuilder()
override fun appendMessage(message: String) {
builder.appendln(message)
}
internal open suspend fun flushMessage() {
if (builder.isNotEmpty()) {
sendMessage(builder.toString().removeSuffix("\n"))
}
}
}
/**
* 控制台指令执行者. 代表由控制台执行指令
*/
object ConsoleCommandSender : AbstractCommandSender() {
override val bot: Nothing? get() = null
override suspend fun sendMessage(message: Message) {
TODO()
// MiraiConsole.logger("[Command]", 0, messageChain.toString())
}
override suspend fun flushMessage() {
super.flushMessage()
builder.clear()
}
// 前端实现
abstract class ConsoleCommandSender internal constructor() : CommandSender {
final override val bot: Nothing? get() = null
}
inline fun Friend.asCommandSender(): FriendCommandSender = FriendCommandSender(this)
fun Friend.asCommandSender(): FriendCommandSender = FriendCommandSender(this)
inline fun Member.asCommandSender(): MemberCommandSender = MemberCommandSender(this)
fun Member.asCommandSender(): MemberCommandSender = MemberCommandSender(this)
inline fun User.asCommandSender(): UserCommandSender {
fun User.asCommandSender(): UserCommandSender {
return when (this) {
is Friend -> this.asCommandSender()
is Member -> this.asCommandSender()
@ -100,7 +84,10 @@ inline fun User.asCommandSender(): UserCommandSender {
* 代表一个用户私聊机器人执行指令
* @see User.asCommandSender
*/
sealed class UserCommandSender : AbstractCommandSender(), BotAwareCommandSender {
sealed class UserCommandSender : CommandSender, BotAwareCommandSender {
/**
* @see MessageEvent.sender
*/
abstract val user: User
/**

View File

@ -7,9 +7,10 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.plugins
package net.mamoe.mirai.console.plugin
import net.mamoe.mirai.console.plugins.builtin.JvmPlugin
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import java.io.File
/**
* 表示一个 mirai-console 插件.
@ -22,4 +23,9 @@ interface Plugin {
* 所属插件加载器实例
*/
val loader: PluginLoader<*, *>
/**
* 插件数据目录
*/
val dataFolder: File
}

View File

@ -9,8 +9,9 @@
@file:Suppress("unused")
package net.mamoe.mirai.console.plugins
package net.mamoe.mirai.console.plugin
import net.mamoe.mirai.console.plugin.jvm.JarPluginLoader
import java.io.File
/**
@ -59,7 +60,7 @@ open class PluginLoadException : RuntimeException {
*/
interface FilePluginLoader<P : Plugin, D : PluginDescription> : PluginLoader<P, D> {
/**
* 所支持的插件文件后缀, '.'. [JarPluginLoader] "jar"
* 所支持的插件文件后缀, '.'. [JarPluginLoader] ".jar"
*/
val fileSuffix: String
}
@ -70,6 +71,9 @@ abstract class AbstractFilePluginLoader<P : Plugin, D : PluginDescription>(
private fun pluginsFilesSequence(): Sequence<File> =
PluginManager.pluginsDir.walk().filter { it.isFile && it.name.endsWith(fileSuffix, ignoreCase = true) }
/**
* 读取扫描到的后缀与 [fileSuffix] 相同的文件中的 [PluginDescription]
*/
protected abstract fun Sequence<File>.mapToDescription(): List<D>
final override fun listPlugins(): List<D> = pluginsFilesSequence().mapToDescription()

View File

@ -9,7 +9,7 @@
@file:Suppress("NOTHING_TO_INLINE")
package net.mamoe.mirai.console.plugins
package net.mamoe.mirai.console.plugin
import kotlinx.atomicfu.locks.withLock
import net.mamoe.mirai.console.MiraiConsole
@ -24,6 +24,7 @@ inline fun PluginLoader<*, *>.unregister() = PluginManager.unregisterPluginLoade
object PluginManager {
val pluginsDir = File(MiraiConsole.rootDir, "plugins").apply { mkdir() }
val pluginsDataFolder = File(MiraiConsole.rootDir, "data").apply { mkdir() }
private val _pluginLoaders: MutableList<PluginLoader<*, *>> = mutableListOf()
private val loadersLock: ReentrantLock = ReentrantLock()

View File

@ -7,7 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.plugins
package net.mamoe.mirai.console.plugin
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer

View File

@ -7,9 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXPOSED_SUPER_CLASS")
package net.mamoe.mirai.console.plugins.builtin
package net.mamoe.mirai.console.plugin.internal
import kotlinx.atomicfu.locks.withLock
import kotlinx.coroutines.CoroutineExceptionHandler
@ -17,91 +15,47 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugins.Plugin
import net.mamoe.mirai.console.plugins.PluginLoader
import net.mamoe.mirai.console.utils.JavaPluginScheduler
import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.console.plugin.PluginManager
import net.mamoe.mirai.console.plugin.jvm.JvmPlugin
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.utils.MiraiLogger
import java.io.File
import java.util.concurrent.locks.ReentrantLock
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
internal val <T> T.job: Job where T : CoroutineScope, T : Plugin get() = this.coroutineContext[Job]!!
/**
* Java Kotlin Jar 插件
*
* @see JavaPlugin Java 插件
* @see KotlinPlugin Kotlin 插件
*/
interface JvmPlugin : Plugin, CoroutineScope {
/** 日志 */
val logger: MiraiLogger
/** 插件描述 */
val description: JvmPluginDescription
/** 所属插件加载器实例 */
override val loader: PluginLoader<*, *> get() = JarPluginLoader
@JvmDefault
fun onLoad() {
}
@JvmDefault
fun onEnable() {
}
@JvmDefault
fun onDisable() {
}
}
/**
* Java 插件的父类
*/
abstract class JavaPlugin @JvmOverloads constructor(
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
) : JvmPlugin, JvmPluginImpl(parentCoroutineContext) {
/**
* Java API Scheduler
*/
val scheduler: JavaPluginScheduler =
JavaPluginScheduler(this.coroutineContext)
}
abstract class KotlinPlugin @JvmOverloads constructor(
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
) : JvmPlugin, JvmPluginImpl(parentCoroutineContext) {
// that's it
}
internal sealed class JvmPluginImpl(
@PublishedApi
internal abstract class JvmPluginImpl(
parentCoroutineContext: CoroutineContext
) : JvmPlugin, CoroutineScope {
) : JvmPlugin,
CoroutineScope {
// region JvmPlugin
/**
* Initialized immediately after construction of [JvmPluginImpl] instance
*/
@Suppress("PropertyName")
internal lateinit var _description: JvmPluginDescription
// for future use
@Suppress("PropertyName")
@JvmField
internal var _intrinsicCoroutineContext: CoroutineContext = EmptyCoroutineContext
override val description: JvmPluginDescription get() = _description
final override val logger: MiraiLogger by lazy { MiraiConsole.newLogger(this._description.name) }
@JvmField
internal val coroutineContextInitializer = {
CoroutineExceptionHandler { _, throwable -> logger.error(throwable) }
.plus(parentCoroutineContext)
.plus(SupervisorJob(parentCoroutineContext[Job])) + _intrinsicCoroutineContext
final override val logger: MiraiLogger by lazy {
MiraiConsole.newLogger(
this._description.name
)
}
private var firstRun = true
override val dataFolder: File by lazy {
File(
PluginManager.pluginsDataFolder,
description.name
).apply { mkdir() }
}
internal fun internalOnDisable() {
firstRun = false
this.onDisable()
@ -116,14 +70,33 @@ internal sealed class JvmPluginImpl(
this.onEnable()
}
// endregion
// region CoroutineScope
// for future use
@Suppress("PropertyName")
@JvmField
internal var _intrinsicCoroutineContext: CoroutineContext =
EmptyCoroutineContext
@JvmField
internal val coroutineContextInitializer = {
CoroutineExceptionHandler { _, throwable -> logger.error(throwable) }
.plus(parentCoroutineContext)
.plus(SupervisorJob(parentCoroutineContext[Job])) + _intrinsicCoroutineContext
}
private fun refreshCoroutineContext(): CoroutineContext {
return coroutineContextInitializer().also { _coroutineContext = it }
}
private val contextUpdateLock: ReentrantLock = ReentrantLock()
private val contextUpdateLock: ReentrantLock =
ReentrantLock()
private var _coroutineContext: CoroutineContext? = null
final override val coroutineContext: CoroutineContext
get() = _coroutineContext
?: contextUpdateLock.withLock { _coroutineContext ?: refreshCoroutineContext() }
// endregion
}

View File

@ -7,7 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.plugins
package net.mamoe.mirai.console.plugin.internal
import net.mamoe.mirai.console.MiraiConsole
import java.io.File
@ -50,7 +50,13 @@ internal class PluginsLoader(private val parentClassLoader: ClassLoader) {
fun loadPluginMainClassByJarFile(pluginName: String, mainClass: String, jarFile: File): Class<*> {
try {
if (!pluginLoaders.containsKey(pluginName)) {
pluginLoaders[pluginName] = PluginClassLoader(pluginName, jarFile, this, parentClassLoader)
pluginLoaders[pluginName] =
PluginClassLoader(
pluginName,
jarFile,
this,
parentClassLoader
)
}
return pluginLoaders[pluginName]!!.loadClass(mainClass)
} catch (e: ClassNotFoundException) {

View File

@ -7,15 +7,16 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.plugins.builtin
package net.mamoe.mirai.console.plugin.jvm
import kotlinx.coroutines.*
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugins.AbstractFilePluginLoader
import net.mamoe.mirai.console.plugins.PluginLoadException
import net.mamoe.mirai.console.plugins.PluginsLoader
import net.mamoe.mirai.console.plugin.AbstractFilePluginLoader
import net.mamoe.mirai.console.plugin.PluginLoadException
import net.mamoe.mirai.console.plugin.internal.JvmPluginImpl
import net.mamoe.mirai.console.plugin.internal.PluginsLoader
import net.mamoe.mirai.console.setting.SettingStorage
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.error
import net.mamoe.yamlkt.Yaml
import java.io.File
import java.net.URL
@ -25,7 +26,7 @@ import kotlin.reflect.full.createInstance
/**
* 内建的 Jar (JVM) 插件加载器
*/
object JarPluginLoader : AbstractFilePluginLoader<JvmPlugin, JvmPluginDescription>("jar"), CoroutineScope {
object JarPluginLoader : AbstractFilePluginLoader<JvmPlugin, JvmPluginDescription>(".jar"), CoroutineScope {
private val logger: MiraiLogger by lazy {
MiraiConsole.newLogger(JarPluginLoader::class.simpleName!!)
}
@ -39,7 +40,8 @@ object JarPluginLoader : AbstractFilePluginLoader<JvmPlugin, JvmPluginDescriptio
}
private val supervisor: Job = coroutineContext[Job]!!
private val classLoader: PluginsLoader = PluginsLoader(this.javaClass.classLoader)
private val classLoader: PluginsLoader =
PluginsLoader(this.javaClass.classLoader)
init {
supervisor.invokeOnCompletion {
@ -47,6 +49,8 @@ object JarPluginLoader : AbstractFilePluginLoader<JvmPlugin, JvmPluginDescriptio
}
}
val settingStorage: SettingStorage = MiraiConsole.jvmSettingStorage
override fun getPluginDescription(plugin: JvmPlugin): JvmPluginDescription = plugin.description
override fun Sequence<File>.mapToDescription(): List<JvmPluginDescription> {

View File

@ -0,0 +1,31 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXPOSED_SUPER_CLASS")
package net.mamoe.mirai.console.plugin.jvm
import net.mamoe.mirai.console.plugin.internal.JvmPluginImpl
import net.mamoe.mirai.console.utils.JavaPluginScheduler
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/**
* Java 插件的父类
*/
abstract class JavaPlugin @JvmOverloads constructor(
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
) : JvmPlugin, JvmPluginImpl(parentCoroutineContext) {
/**
* Java API Scheduler
*/
val scheduler: JavaPluginScheduler =
JavaPluginScheduler(this.coroutineContext)
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXPOSED_SUPER_CLASS")
package net.mamoe.mirai.console.plugin.jvm
import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.utils.MiraiLogger
/**
* Java Kotlin Jar 插件
*
* @see JavaPlugin Java 插件
* @see KotlinPlugin Kotlin 插件
*/
interface JvmPlugin : Plugin, CoroutineScope {
/** 日志 */
val logger: MiraiLogger
/** 插件描述 */
val description: JvmPluginDescription
/** 所属插件加载器实例 */
override val loader: JarPluginLoader get() = JarPluginLoader
@JvmDefault
fun onLoad() {
}
@JvmDefault
fun onEnable() {
}
@JvmDefault
fun onDisable() {
}
}

View File

@ -7,15 +7,15 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.plugins.builtin
package net.mamoe.mirai.console.plugin.jvm
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import net.mamoe.mirai.console.plugins.FilePluginDescription
import net.mamoe.mirai.console.plugins.PluginDependency
import net.mamoe.mirai.console.plugins.PluginDescription
import net.mamoe.mirai.console.plugins.PluginKind
import net.mamoe.mirai.console.plugin.FilePluginDescription
import net.mamoe.mirai.console.plugin.PluginDependency
import net.mamoe.mirai.console.plugin.PluginDescription
import net.mamoe.mirai.console.plugin.PluginKind
import java.io.File
@Serializable

View File

@ -0,0 +1,42 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXPOSED_SUPER_CLASS")
package net.mamoe.mirai.console.plugin.jvm
import net.mamoe.mirai.console.plugin.internal.JvmPluginImpl
import net.mamoe.mirai.console.plugin.internal.job
import net.mamoe.mirai.console.setting.Setting
import net.mamoe.mirai.console.setting.Value
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/**
* Kotlin 插件的父类
*/
abstract class KotlinPlugin @JvmOverloads constructor(
parentCoroutineContext: CoroutineContext = EmptyCoroutineContext
) : JvmPlugin, JvmPluginImpl(parentCoroutineContext) {
abstract inner class PluginSetting : Setting() {
private val track =
@Suppress("LeakingThis")
JarPluginLoader.settingStorage.trackOn(this)
init {
this@KotlinPlugin.job.invokeOnCompletion {
track.close()
}
}
override fun onElementChanged(value: Value<*>) {
TODO()
}
}
}

View File

@ -7,15 +7,17 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("NOTHING_TO_INLINE")
@file:Suppress("NOTHING_TO_INLINE", "unused")
package net.mamoe.mirai.console.setting
import kotlinx.serialization.KSerializer
import net.mamoe.mirai.console.setting.internal.SettingImpl
import net.mamoe.mirai.console.setting.internal.serialNameOrPropertyName
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty0
import kotlin.reflect.full.findAnnotation
/**
@ -33,6 +35,23 @@ typealias Comment = net.mamoe.yamlkt.Comment
*/
@Suppress("EXPOSED_SUPER_CLASS")
abstract class Setting : SettingImpl() {
/**
* 表示这个配置的嵌套对象, 自动绑定数据更新.
*/
abstract inner class Inner : Setting() {
internal lateinit var attachedValue: Value<*>
override fun onElementChanged(value: Value<*>) {
this@Setting.onElementChanged(attachedValue)
}
}
data class PropertyInfo(
val serialName: String,
val annotations: List<Annotation>,
val propertyOriginalName: String?
)
/**
* 这个配置的名称, 仅对于顶层配置有效.
*/
@ -43,6 +62,33 @@ abstract class Setting : SettingImpl() {
?: error("Names should be assigned to anonymous classes manually by overriding serialName")
// for Java only
fun <T : Any> addProperty(
propertyInfo: PropertyInfo,
value: Value<*>
): Value<*> {
if (built) error("The Setting is already serialized so it's structure is immutable.")
valueList.add(value to propertyInfo)
return value
}
/**
* 获取这个属性的真实 [Value] 委托
*/
@get:JvmSynthetic
val <R : Any> KProperty0<R>.correspondingValue: Value<R>
@Suppress("UNCHECKED_CAST")
get() = findCorrespondingValue(this)
?: throw NoSuchElementException("No corresponding Value found for property $this")
/**
* 获取这个属性的真实 [Value] 委托
*/
fun <R : Any> findCorrespondingValue(property: KProperty0<R>): Value<R>? {
@Suppress("UNCHECKED_CAST")
return this@Setting.valueList.firstOrNull { it.second.propertyOriginalName == property.name }?.first as Value<R>?
}
/**
* 提供属性委托, 并添加这个对象的自动保存跟踪.
*/
@ -52,10 +98,12 @@ abstract class Setting : SettingImpl() {
property: KProperty<*>
): ReadWriteProperty<Setting, T> {
if (built) error("The Setting is already serialized so it's structure is immutable.")
valueList.add(this to property)
valueList.add(this to PropertyInfo(property.serialNameOrPropertyName, property.annotations, property.name))
return this
}
abstract override fun onElementChanged(value: Value<*>)
override fun toString(): String = yamlForToString.stringify(this.serializer, this)
}

View File

@ -0,0 +1,65 @@
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
package net.mamoe.mirai.console.setting
import kotlinx.atomicfu.locks.withLock
import kotlinx.serialization.*
import kotlinx.serialization.internal.getChecked
import net.mamoe.mirai.console.setting.internal.SettingSerializerMark
import java.io.Closeable
import java.io.File
import java.util.concurrent.locks.ReentrantLock
/**
* [Setting] 存储方式
*/
interface SettingStorage {
interface TrackedSetting : Closeable {
fun save()
fun update()
override fun close()
}
fun trackOn(setting: Setting): TrackedSetting
fun saveAll()
fun updateAll()
}
class SingleFileSettingStorage(
val file: File
) : SettingStorage {
private val descriptor: MutableList<Setting> = ArrayList()
private val updaterSerializer: KSerializer<SettingSerializerMark> = object : KSerializer<SettingSerializerMark> {
override val descriptor: SerialDescriptor = SerialDescriptor("SingleFileSettingStorage") {
TODO()
}
override fun deserialize(decoder: Decoder): SettingSerializerMark {
TODO("Not yet implemented")
}
override fun serialize(encoder: Encoder, value: SettingSerializerMark) {
TODO("Not yet implemented")
}
}
init {
require(file.isFile) { "file $file is not a file" }
require(file.canRead()) { "file $file is not readable" }
}
override fun trackOn(setting: Setting): SettingStorage.TrackedSetting {
TODO("Not yet implemented")
}
override fun saveAll() {
TODO("Not yet implemented")
}
override fun updateAll() {
TODO("Not yet implemented")
}
}

View File

@ -124,7 +124,11 @@ fun <T : Setting> Setting.value(default: T): Value<T> {
require(this::class != default::class) {
"Recursive nesting is prohibited"
}
return valueImpl(default)
return valueImpl(default).also {
if (default is Setting.Inner) {
default.attachedValue = it
}
}
}
inline fun <T : Setting> Setting.value(default: T, crossinline initializer: T.() -> Unit): Value<T> =

View File

@ -0,0 +1,32 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console.setting.internal
import kotlinx.coroutines.Job
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.setting.Setting
import net.mamoe.mirai.console.setting.Value
internal abstract class ConsoleBuiltInSetting : Setting() {
private val track =
@Suppress("LeakingThis")
MiraiConsole.jvmSettingStorage.trackOn(this)
init {
MiraiConsole.coroutineContext[Job]!!.invokeOnCompletion {
track.close()
}
}
override fun onElementChanged(value: Value<*>) {
TODO()
}
}

View File

@ -9,7 +9,10 @@
package net.mamoe.mirai.console.setting.internal
import kotlinx.serialization.*
import kotlinx.serialization.Decoder
import kotlinx.serialization.Encoder
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialDescriptor
import kotlinx.serialization.builtins.*
import net.mamoe.mirai.console.setting.*
@ -31,7 +34,7 @@ internal fun Setting.valueImpl(default: Int): IntValue {
onElementChanged(this)
}
}
override val serializer = Int.serializer()
override val serializer get() = Int.serializer()
}
}
@ -46,7 +49,7 @@ internal fun Setting.valueImpl(default: Short): ShortValue {
onElementChanged(this)
}
}
override val serializer = Short.serializer()
override val serializer get() = Short.serializer()
}
}
@ -61,7 +64,7 @@ internal fun Setting.valueImpl(default: Byte): ByteValue {
onElementChanged(this)
}
}
override val serializer = Byte.serializer()
override val serializer get() = Byte.serializer()
}
}
@ -76,7 +79,7 @@ internal fun Setting.valueImpl(default: Long): LongValue {
onElementChanged(this)
}
}
override val serializer = Long.serializer()
override val serializer get() = Long.serializer()
}
}
@ -91,7 +94,7 @@ internal fun Setting.valueImpl(default: Float): FloatValue {
onElementChanged(this)
}
}
override val serializer = Float.serializer()
override val serializer get() = Float.serializer()
}
}
@ -106,7 +109,7 @@ internal fun Setting.valueImpl(default: Double): DoubleValue {
onElementChanged(this)
}
}
override val serializer = Double.serializer()
override val serializer get() = Double.serializer()
}
}
@ -121,7 +124,7 @@ internal fun Setting.valueImpl(default: Boolean): BooleanValue {
onElementChanged(this)
}
}
override val serializer = Boolean.serializer()
override val serializer get() = Boolean.serializer()
}
}
@ -136,7 +139,7 @@ internal fun Setting.valueImpl(default: Char): CharValue {
onElementChanged(this)
}
}
override val serializer = Char.serializer()
override val serializer get() = Char.serializer()
}
}
@ -151,7 +154,7 @@ internal fun Setting.valueImpl(default: String): StringValue {
onElementChanged(this)
}
}
override val serializer = String.serializer()
override val serializer get() = String.serializer()
}
}
@ -166,7 +169,7 @@ internal fun Setting.valueImpl(default: IntArray): IntArrayValue {
onElementChanged(this)
}
}
override val serializer = IntArraySerializer()
override val serializer get() = IntArraySerializer()
}
}
@ -181,7 +184,7 @@ internal fun Setting.valueImpl(default: ShortArray): ShortArrayValue {
onElementChanged(this)
}
}
override val serializer = ShortArraySerializer()
override val serializer get() = ShortArraySerializer()
}
}
@ -196,7 +199,7 @@ internal fun Setting.valueImpl(default: ByteArray): ByteArrayValue {
onElementChanged(this)
}
}
override val serializer = ByteArraySerializer()
override val serializer get() = ByteArraySerializer()
}
}
@ -211,7 +214,7 @@ internal fun Setting.valueImpl(default: LongArray): LongArrayValue {
onElementChanged(this)
}
}
override val serializer = LongArraySerializer()
override val serializer get() = LongArraySerializer()
}
}
@ -226,7 +229,7 @@ internal fun Setting.valueImpl(default: FloatArray): FloatArrayValue {
onElementChanged(this)
}
}
override val serializer = FloatArraySerializer()
override val serializer get() = FloatArraySerializer()
}
}
@ -241,7 +244,7 @@ internal fun Setting.valueImpl(default: DoubleArray): DoubleArrayValue {
onElementChanged(this)
}
}
override val serializer = DoubleArraySerializer()
override val serializer get() = DoubleArraySerializer()
}
}
@ -256,7 +259,7 @@ internal fun Setting.valueImpl(default: BooleanArray): BooleanArrayValue {
onElementChanged(this)
}
}
override val serializer = BooleanArraySerializer()
override val serializer get() = BooleanArraySerializer()
}
}
@ -271,7 +274,7 @@ internal fun Setting.valueImpl(default: CharArray): CharArrayValue {
onElementChanged(this)
}
}
override val serializer = CharArraySerializer()
override val serializer get() = CharArraySerializer()
}
}
@ -286,7 +289,7 @@ internal fun Setting.valueImpl(default: Array<Int>): TypedIntArrayValue {
onElementChanged(this)
}
}
override val serializer = ArraySerializer(Int.serializer())
override val serializer get() = ArraySerializer(Int.serializer())
}
}
@ -301,7 +304,7 @@ internal fun Setting.valueImpl(default: Array<Short>): TypedShortArrayValue {
onElementChanged(this)
}
}
override val serializer = ArraySerializer(Short.serializer())
override val serializer get() = ArraySerializer(Short.serializer())
}
}
@ -316,7 +319,7 @@ internal fun Setting.valueImpl(default: Array<Byte>): TypedByteArrayValue {
onElementChanged(this)
}
}
override val serializer = ArraySerializer(Byte.serializer())
override val serializer get() = ArraySerializer(Byte.serializer())
}
}
@ -331,7 +334,7 @@ internal fun Setting.valueImpl(default: Array<Long>): TypedLongArrayValue {
onElementChanged(this)
}
}
override val serializer = ArraySerializer(Long.serializer())
override val serializer get() = ArraySerializer(Long.serializer())
}
}
@ -346,7 +349,7 @@ internal fun Setting.valueImpl(default: Array<Float>): TypedFloatArrayValue {
onElementChanged(this)
}
}
override val serializer = ArraySerializer(Float.serializer())
override val serializer get() = ArraySerializer(Float.serializer())
}
}
@ -361,7 +364,7 @@ internal fun Setting.valueImpl(default: Array<Double>): TypedDoubleArrayValue {
onElementChanged(this)
}
}
override val serializer = ArraySerializer(Double.serializer())
override val serializer get() = ArraySerializer(Double.serializer())
}
}
@ -376,7 +379,7 @@ internal fun Setting.valueImpl(default: Array<Boolean>): TypedBooleanArrayValue
onElementChanged(this)
}
}
override val serializer = ArraySerializer(Boolean.serializer())
override val serializer get() = ArraySerializer(Boolean.serializer())
}
}
@ -391,7 +394,7 @@ internal fun Setting.valueImpl(default: Array<Char>): TypedCharArrayValue {
onElementChanged(this)
}
}
override val serializer = ArraySerializer(Char.serializer())
override val serializer get() = ArraySerializer(Char.serializer())
}
}
@ -406,7 +409,7 @@ internal fun Setting.valueImpl(default: Array<String>): TypedStringArrayValue {
onElementChanged(this)
}
}
override val serializer = ArraySerializer(String.serializer())
override val serializer get() = ArraySerializer(String.serializer())
}
}
@ -422,7 +425,7 @@ internal fun Setting.valueImpl(default: List<Int>): IntListValue {
onElementChanged(this)
}
}
override val serializer = ListSerializer(Int.serializer())
override val serializer get() = ListSerializer(Int.serializer())
}
}
@ -438,7 +441,7 @@ internal fun Setting.valueImpl(default: List<Short>): ShortListValue {
onElementChanged(this)
}
}
override val serializer = ListSerializer(Short.serializer())
override val serializer get() = ListSerializer(Short.serializer())
}
}
@ -454,7 +457,7 @@ internal fun Setting.valueImpl(default: List<Byte>): ByteListValue {
onElementChanged(this)
}
}
override val serializer = ListSerializer(Byte.serializer())
override val serializer get() = ListSerializer(Byte.serializer())
}
}
@ -470,7 +473,7 @@ internal fun Setting.valueImpl(default: List<Long>): LongListValue {
onElementChanged(this)
}
}
override val serializer = ListSerializer(Long.serializer())
override val serializer get() = ListSerializer(Long.serializer())
}
}
@ -486,7 +489,7 @@ internal fun Setting.valueImpl(default: List<Float>): FloatListValue {
onElementChanged(this)
}
}
override val serializer = ListSerializer(Float.serializer())
override val serializer get() = ListSerializer(Float.serializer())
}
}
@ -502,7 +505,7 @@ internal fun Setting.valueImpl(default: List<Double>): DoubleListValue {
onElementChanged(this)
}
}
override val serializer = ListSerializer(Double.serializer())
override val serializer get() = ListSerializer(Double.serializer())
}
}
@ -518,7 +521,7 @@ internal fun Setting.valueImpl(default: List<Boolean>): BooleanListValue {
onElementChanged(this)
}
}
override val serializer = ListSerializer(Boolean.serializer())
override val serializer get() = ListSerializer(Boolean.serializer())
}
}
@ -534,7 +537,7 @@ internal fun Setting.valueImpl(default: List<Char>): CharListValue {
onElementChanged(this)
}
}
override val serializer = ListSerializer(Char.serializer())
override val serializer get() = ListSerializer(Char.serializer())
}
}
@ -550,7 +553,7 @@ internal fun Setting.valueImpl(default: List<String>): StringListValue {
onElementChanged(this)
}
}
override val serializer = ListSerializer(String.serializer())
override val serializer get() = ListSerializer(String.serializer())
}
}
@ -566,7 +569,7 @@ internal fun Setting.valueImpl(default: Set<Int>): IntSetValue {
onElementChanged(this)
}
}
override val serializer = SetSerializer(Int.serializer())
override val serializer get() = SetSerializer(Int.serializer())
}
}
@ -582,7 +585,7 @@ internal fun Setting.valueImpl(default: Set<Short>): ShortSetValue {
onElementChanged(this)
}
}
override val serializer = SetSerializer(Short.serializer())
override val serializer get() = SetSerializer(Short.serializer())
}
}
@ -598,7 +601,7 @@ internal fun Setting.valueImpl(default: Set<Byte>): ByteSetValue {
onElementChanged(this)
}
}
override val serializer = SetSerializer(Byte.serializer())
override val serializer get() = SetSerializer(Byte.serializer())
}
}
@ -614,7 +617,7 @@ internal fun Setting.valueImpl(default: Set<Long>): LongSetValue {
onElementChanged(this)
}
}
override val serializer = SetSerializer(Long.serializer())
override val serializer get() = SetSerializer(Long.serializer())
}
}
@ -630,7 +633,7 @@ internal fun Setting.valueImpl(default: Set<Float>): FloatSetValue {
onElementChanged(this)
}
}
override val serializer = SetSerializer(Float.serializer())
override val serializer get() = SetSerializer(Float.serializer())
}
}
@ -646,7 +649,7 @@ internal fun Setting.valueImpl(default: Set<Double>): DoubleSetValue {
onElementChanged(this)
}
}
override val serializer = SetSerializer(Double.serializer())
override val serializer get() = SetSerializer(Double.serializer())
}
}
@ -662,7 +665,7 @@ internal fun Setting.valueImpl(default: Set<Boolean>): BooleanSetValue {
onElementChanged(this)
}
}
override val serializer = SetSerializer(Boolean.serializer())
override val serializer get() = SetSerializer(Boolean.serializer())
}
}
@ -678,7 +681,7 @@ internal fun Setting.valueImpl(default: Set<Char>): CharSetValue {
onElementChanged(this)
}
}
override val serializer = SetSerializer(Char.serializer())
override val serializer get() = SetSerializer(Char.serializer())
}
}
@ -694,7 +697,7 @@ internal fun Setting.valueImpl(default: Set<String>): StringSetValue {
onElementChanged(this)
}
}
override val serializer = SetSerializer(String.serializer())
override val serializer get() = SetSerializer(String.serializer())
}
}
@ -705,7 +708,7 @@ internal fun Setting.valueImpl(
): MutableIntListValue {
var internalValue: MutableList<Int> = default
val delegt = dynamicMutableList{ internalValue }
val delegt = dynamicMutableList { internalValue }
return object : MutableIntListValue(), MutableList<Int> by delegt {
override var value: MutableList<Int>
get() = internalValue
@ -720,7 +723,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableList<Int>> = object : KSerializer<MutableList<Int>> {
private val delegate = ListSerializer(Int.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Int> {
return delegate.deserialize(decoder).toMutableList().observable {
@ -741,7 +744,7 @@ internal fun Setting.valueImpl(
): MutableShortListValue {
var internalValue: MutableList<Short> = default
val delegt = dynamicMutableList{ internalValue }
val delegt = dynamicMutableList { internalValue }
return object : MutableShortListValue(), MutableList<Short> by delegt {
override var value: MutableList<Short>
get() = internalValue
@ -756,7 +759,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableList<Short>> = object : KSerializer<MutableList<Short>> {
private val delegate = ListSerializer(Short.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Short> {
return delegate.deserialize(decoder).toMutableList().observable {
@ -777,7 +780,7 @@ internal fun Setting.valueImpl(
): MutableByteListValue {
var internalValue: MutableList<Byte> = default
val delegt = dynamicMutableList{ internalValue }
val delegt = dynamicMutableList { internalValue }
return object : MutableByteListValue(), MutableList<Byte> by delegt {
override var value: MutableList<Byte>
get() = internalValue
@ -792,7 +795,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableList<Byte>> = object : KSerializer<MutableList<Byte>> {
private val delegate = ListSerializer(Byte.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Byte> {
return delegate.deserialize(decoder).toMutableList().observable {
@ -813,7 +816,7 @@ internal fun Setting.valueImpl(
): MutableLongListValue {
var internalValue: MutableList<Long> = default
val delegt = dynamicMutableList{ internalValue }
val delegt = dynamicMutableList { internalValue }
return object : MutableLongListValue(), MutableList<Long> by delegt {
override var value: MutableList<Long>
get() = internalValue
@ -828,7 +831,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableList<Long>> = object : KSerializer<MutableList<Long>> {
private val delegate = ListSerializer(Long.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Long> {
return delegate.deserialize(decoder).toMutableList().observable {
@ -849,7 +852,7 @@ internal fun Setting.valueImpl(
): MutableFloatListValue {
var internalValue: MutableList<Float> = default
val delegt = dynamicMutableList{ internalValue }
val delegt = dynamicMutableList { internalValue }
return object : MutableFloatListValue(), MutableList<Float> by delegt {
override var value: MutableList<Float>
get() = internalValue
@ -864,7 +867,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableList<Float>> = object : KSerializer<MutableList<Float>> {
private val delegate = ListSerializer(Float.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Float> {
return delegate.deserialize(decoder).toMutableList().observable {
@ -885,7 +888,7 @@ internal fun Setting.valueImpl(
): MutableDoubleListValue {
var internalValue: MutableList<Double> = default
val delegt = dynamicMutableList{ internalValue }
val delegt = dynamicMutableList { internalValue }
return object : MutableDoubleListValue(), MutableList<Double> by delegt {
override var value: MutableList<Double>
get() = internalValue
@ -900,7 +903,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableList<Double>> = object : KSerializer<MutableList<Double>> {
private val delegate = ListSerializer(Double.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Double> {
return delegate.deserialize(decoder).toMutableList().observable {
@ -921,7 +924,7 @@ internal fun Setting.valueImpl(
): MutableBooleanListValue {
var internalValue: MutableList<Boolean> = default
val delegt = dynamicMutableList{ internalValue }
val delegt = dynamicMutableList { internalValue }
return object : MutableBooleanListValue(), MutableList<Boolean> by delegt {
override var value: MutableList<Boolean>
get() = internalValue
@ -936,7 +939,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableList<Boolean>> = object : KSerializer<MutableList<Boolean>> {
private val delegate = ListSerializer(Boolean.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Boolean> {
return delegate.deserialize(decoder).toMutableList().observable {
@ -957,7 +960,7 @@ internal fun Setting.valueImpl(
): MutableCharListValue {
var internalValue: MutableList<Char> = default
val delegt = dynamicMutableList{ internalValue }
val delegt = dynamicMutableList { internalValue }
return object : MutableCharListValue(), MutableList<Char> by delegt {
override var value: MutableList<Char>
get() = internalValue
@ -972,7 +975,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableList<Char>> = object : KSerializer<MutableList<Char>> {
private val delegate = ListSerializer(Char.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<Char> {
return delegate.deserialize(decoder).toMutableList().observable {
@ -993,7 +996,7 @@ internal fun Setting.valueImpl(
): MutableStringListValue {
var internalValue: MutableList<String> = default
val delegt = dynamicMutableList{ internalValue }
val delegt = dynamicMutableList { internalValue }
return object : MutableStringListValue(), MutableList<String> by delegt {
override var value: MutableList<String>
get() = internalValue
@ -1008,7 +1011,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableList<String>> = object : KSerializer<MutableList<String>> {
private val delegate = ListSerializer(String.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableList<String> {
return delegate.deserialize(decoder).toMutableList().observable {
@ -1029,7 +1032,7 @@ internal fun Setting.valueImpl(
): MutableIntSetValue {
var internalValue: MutableSet<Int> = default
val delegt = dynamicMutableSet{ internalValue }
val delegt = dynamicMutableSet { internalValue }
return object : MutableIntSetValue(), MutableSet<Int> by delegt {
override var value: MutableSet<Int>
get() = internalValue
@ -1044,7 +1047,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableSet<Int>> = object : KSerializer<MutableSet<Int>> {
private val delegate = SetSerializer(Int.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Int> {
return delegate.deserialize(decoder).toMutableSet().observable {
@ -1065,7 +1068,7 @@ internal fun Setting.valueImpl(
): MutableShortSetValue {
var internalValue: MutableSet<Short> = default
val delegt = dynamicMutableSet{ internalValue }
val delegt = dynamicMutableSet { internalValue }
return object : MutableShortSetValue(), MutableSet<Short> by delegt {
override var value: MutableSet<Short>
get() = internalValue
@ -1080,7 +1083,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableSet<Short>> = object : KSerializer<MutableSet<Short>> {
private val delegate = SetSerializer(Short.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Short> {
return delegate.deserialize(decoder).toMutableSet().observable {
@ -1101,7 +1104,7 @@ internal fun Setting.valueImpl(
): MutableByteSetValue {
var internalValue: MutableSet<Byte> = default
val delegt = dynamicMutableSet{ internalValue }
val delegt = dynamicMutableSet { internalValue }
return object : MutableByteSetValue(), MutableSet<Byte> by delegt {
override var value: MutableSet<Byte>
get() = internalValue
@ -1116,7 +1119,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableSet<Byte>> = object : KSerializer<MutableSet<Byte>> {
private val delegate = SetSerializer(Byte.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Byte> {
return delegate.deserialize(decoder).toMutableSet().observable {
@ -1137,7 +1140,7 @@ internal fun Setting.valueImpl(
): MutableLongSetValue {
var internalValue: MutableSet<Long> = default
val delegt = dynamicMutableSet{ internalValue }
val delegt = dynamicMutableSet { internalValue }
return object : MutableLongSetValue(), MutableSet<Long> by delegt {
override var value: MutableSet<Long>
get() = internalValue
@ -1152,7 +1155,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableSet<Long>> = object : KSerializer<MutableSet<Long>> {
private val delegate = SetSerializer(Long.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Long> {
return delegate.deserialize(decoder).toMutableSet().observable {
@ -1173,7 +1176,7 @@ internal fun Setting.valueImpl(
): MutableFloatSetValue {
var internalValue: MutableSet<Float> = default
val delegt = dynamicMutableSet{ internalValue }
val delegt = dynamicMutableSet { internalValue }
return object : MutableFloatSetValue(), MutableSet<Float> by delegt {
override var value: MutableSet<Float>
get() = internalValue
@ -1188,7 +1191,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableSet<Float>> = object : KSerializer<MutableSet<Float>> {
private val delegate = SetSerializer(Float.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Float> {
return delegate.deserialize(decoder).toMutableSet().observable {
@ -1209,7 +1212,7 @@ internal fun Setting.valueImpl(
): MutableDoubleSetValue {
var internalValue: MutableSet<Double> = default
val delegt = dynamicMutableSet{ internalValue }
val delegt = dynamicMutableSet { internalValue }
return object : MutableDoubleSetValue(), MutableSet<Double> by delegt {
override var value: MutableSet<Double>
get() = internalValue
@ -1224,7 +1227,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableSet<Double>> = object : KSerializer<MutableSet<Double>> {
private val delegate = SetSerializer(Double.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Double> {
return delegate.deserialize(decoder).toMutableSet().observable {
@ -1245,7 +1248,7 @@ internal fun Setting.valueImpl(
): MutableBooleanSetValue {
var internalValue: MutableSet<Boolean> = default
val delegt = dynamicMutableSet{ internalValue }
val delegt = dynamicMutableSet { internalValue }
return object : MutableBooleanSetValue(), MutableSet<Boolean> by delegt {
override var value: MutableSet<Boolean>
get() = internalValue
@ -1260,7 +1263,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableSet<Boolean>> = object : KSerializer<MutableSet<Boolean>> {
private val delegate = SetSerializer(Boolean.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Boolean> {
return delegate.deserialize(decoder).toMutableSet().observable {
@ -1281,7 +1284,7 @@ internal fun Setting.valueImpl(
): MutableCharSetValue {
var internalValue: MutableSet<Char> = default
val delegt = dynamicMutableSet{ internalValue }
val delegt = dynamicMutableSet { internalValue }
return object : MutableCharSetValue(), MutableSet<Char> by delegt {
override var value: MutableSet<Char>
get() = internalValue
@ -1296,7 +1299,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableSet<Char>> = object : KSerializer<MutableSet<Char>> {
private val delegate = SetSerializer(Char.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<Char> {
return delegate.deserialize(decoder).toMutableSet().observable {
@ -1317,7 +1320,7 @@ internal fun Setting.valueImpl(
): MutableStringSetValue {
var internalValue: MutableSet<String> = default
val delegt = dynamicMutableSet{ internalValue }
val delegt = dynamicMutableSet { internalValue }
return object : MutableStringSetValue(), MutableSet<String> by delegt {
override var value: MutableSet<String>
get() = internalValue
@ -1332,7 +1335,7 @@ internal fun Setting.valueImpl(
override val serializer: KSerializer<MutableSet<String>> = object : KSerializer<MutableSet<String>> {
private val delegate = SetSerializer(String.serializer())
override val descriptor: SerialDescriptor = delegate.descriptor
override val descriptor: SerialDescriptor get() = delegate.descriptor
override fun deserialize(decoder: Decoder): MutableSet<String> {
return delegate.deserialize(decoder).toMutableSet().observable {
@ -1359,7 +1362,7 @@ internal fun <T : Setting> Setting.valueImpl(default: T): Value<T> {
onElementChanged(this)
}
}
override val serializer = object : KSerializer<T>{
override val serializer = object : KSerializer<T> {
override val descriptor: SerialDescriptor
get() = internalValue.updaterSerializer.descriptor

View File

@ -24,7 +24,7 @@ import kotlin.reflect.full.findAnnotation
internal abstract class SettingImpl {
@JvmField
internal var valueList: MutableList<Pair<Value<*>, KProperty<*>>> = mutableListOf()
internal var valueList: MutableList<Pair<Value<*>, Setting.PropertyInfo>> = mutableListOf()
@JvmField
internal var built: Boolean = false
@ -53,9 +53,7 @@ internal abstract class SettingImpl {
}
}
internal fun onElementChanged(value: Value<*>) {
println("my value changed!")
}
abstract fun onElementChanged(value: Value<*>)
companion object {
@JvmStatic
@ -78,8 +76,9 @@ internal class SettingUpdaterSerializer(
override val descriptor: SerialDescriptor by lazy {
@OptIn(MiraiExperimentalAPI::class)
SerialDescriptor(instance.serialName) {
for ((value, property) in instance.valueList) {
element(property.serialNameOrPropertyName, value.serializer.descriptor, annotations, true)
for ((value, prop) in instance.valueList) {
val (serialName, annotations) = prop
element(serialName, value.serializer.descriptor, annotations, true)
}
}
}

View File

@ -17,7 +17,9 @@ import net.mamoe.mirai.console.setting.*
import net.mamoe.yamlkt.YamlDynamicSerializer
import kotlin.internal.LowPriorityInOverloadResolution
import kotlin.reflect.KClass
import kotlin.reflect.KType
import kotlin.reflect.full.createInstance
import kotlin.reflect.typeOf
/// region MUTABLE LIST
@ -291,6 +293,7 @@ internal fun <T : Any> Setting.valueImpl(
/**
* For primitives and serializable only
*/
@OptIn(ExperimentalStdlibApi::class)
@PublishedApi
@LowPriorityInOverloadResolution
internal inline fun <reified T : Any> Setting.valueImpl(default: T): Value<T> =

View File

@ -6,14 +6,21 @@
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:JvmName("BotManagers")
package net.mamoe.mirai.console.utils
import kotlinx.atomicfu.locks.withLock
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugins.*
import net.mamoe.mirai.console.setting.Value
import net.mamoe.mirai.console.setting.internal.ConsoleBuiltInSetting
import net.mamoe.mirai.console.setting.value
import net.mamoe.mirai.contact.User
import java.io.File
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.Condition
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
import kotlin.properties.ReadWriteProperty
/**
@ -32,15 +39,4 @@ fun Bot.removeManager(long: Long) {
}
val Bot.managers: List<Long>
get() {
TODO()
}
fun Bot.checkManager(long: Long): Boolean {
return this.managers.contains(long)
}
fun getBotManagers(bot: Bot): List<Long> {
return bot.managers
}
get() = TODO()

View File

@ -0,0 +1,8 @@
package net.mamoe.mirai.console.utils
/**
* 表明这个 API 是为了让 Java 使用者调用更方便. Kotlin 使用者不应该使用这些 API.
*/
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.CLASS)
internal annotation class JavaFriendlyAPI

View File

@ -11,7 +11,7 @@ package net.mamoe.mirai.console.utils
import kotlinx.coroutines.*
import kotlinx.coroutines.future.future
import net.mamoe.mirai.console.plugins.builtin.JavaPlugin
import net.mamoe.mirai.console.plugin.jvm.JavaPlugin
import java.util.concurrent.Callable
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Future

View File

@ -12,14 +12,20 @@
package net.mamoe.mirai.console.command
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.plugins.builtin.KotlinPlugin
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.console.setting.value
import net.mamoe.mirai.message.data.*
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
val plugin: KotlinPlugin = object : KotlinPlugin() {
val plugin = MyPlugin()
class MyPlugin : KotlinPlugin() {
inner class MySetting : PluginSetting() {
val int by value(1)
}
}
/*
@ -94,9 +100,6 @@ internal inline fun withSender(block: CommandSender.() -> Unit): MessageChain {
result.add(message)
}
override fun appendMessage(message: String) {
result.add(message)
}
}
sender.let(block)
return result.asMessageChain()