mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-11 02:50:15 +08:00
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:
commit
b66142545c
@ -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;
|
||||
|
@ -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> =
|
||||
|
@ -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"
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
}
|
@ -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()
|
@ -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()
|
@ -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
|
@ -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
|
||||
}
|
@ -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) {
|
@ -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> {
|
@ -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)
|
||||
}
|
@ -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() {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
@ -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> =
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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> =
|
||||
|
@ -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()
|
@ -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
|
@ -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
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user