mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-06 08:00:10 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
def0e371c6
@ -27,7 +27,7 @@ object MiraiConsole {
|
|||||||
|
|
||||||
var path: String = System.getProperty("user.dir")
|
var path: String = System.getProperty("user.dir")
|
||||||
|
|
||||||
val version = " 0.13"
|
val version = "0.13"
|
||||||
val build = "Beta"
|
val build = "Beta"
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
@ -42,14 +42,13 @@ object MiraiConsole {
|
|||||||
logger("Mirai为开源项目,请自觉遵守开源项目协议")
|
logger("Mirai为开源项目,请自觉遵守开源项目协议")
|
||||||
logger("Powered by Mamoe Technology")
|
logger("Powered by Mamoe Technology")
|
||||||
logger()
|
logger()
|
||||||
logger("\"/login qqnumber qqpassword \" to login a bot")
|
|
||||||
logger("\"/login qq号 qq密码 \" 来登陆一个BOT")
|
|
||||||
|
|
||||||
MiraiProperties()
|
|
||||||
CommandManager.register(DefaultCommands.DefaultLoginCommand())
|
CommandManager.register(DefaultCommands.DefaultLoginCommand())
|
||||||
pluginManager.loadPlugins()
|
pluginManager.loadPlugins()
|
||||||
CommandListener.start()
|
CommandListener.start()
|
||||||
println(MiraiProperties.HTTP_API_ENABLE)
|
println(MiraiProperties.HTTP_API_ENABLE)
|
||||||
|
logger("\"/login qqnumber qqpassword \" to login a bot")
|
||||||
|
logger("\"/login qq号 qq密码 \" 来登陆一个BOT")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
@ -117,22 +116,16 @@ object MiraiConsole {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object MiraiProperties {
|
object MiraiProperties {
|
||||||
val init = !File("$path/mirai.json").exists()
|
var config = File("$path/mirai.json").loadAsConfig()
|
||||||
|
|
||||||
var config = Config.load("$path/mirai.json")
|
var HTTP_API_ENABLE: Boolean by config.withDefaultWrite { true }
|
||||||
|
var HTTP_API_PORT: Int by config.withDefaultWrite { 8080 }
|
||||||
var HTTP_API_ENABLE: Boolean by config.withDefault { true }
|
var HTTP_API_AUTH_KEY: String by config.withDefaultWriteSave {
|
||||||
var HTTP_API_PORT: Int by config.withDefault { 8080 }
|
"InitKey".also {
|
||||||
var HTTP_API_AUTH_KEY: String by config
|
logger("Mirai HTTPAPI auth key 已随机生成 请注意修改")
|
||||||
|
} + generateSessionKey()
|
||||||
operator fun invoke() {
|
|
||||||
if (init) {
|
|
||||||
HTTP_API_AUTH_KEY = "INITKEY" + generateSessionKey()
|
|
||||||
logger("Mirai HTTPAPI authkey 已随机生成, 请注意修改")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,12 +14,11 @@ import com.alibaba.fastjson.JSONObject
|
|||||||
import com.alibaba.fastjson.TypeReference
|
import com.alibaba.fastjson.TypeReference
|
||||||
import com.alibaba.fastjson.parser.Feature
|
import com.alibaba.fastjson.parser.Feature
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import net.mamoe.mirai.utils.cryptor.contentToString
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.function.BiConsumer
|
import java.util.concurrent.ConcurrentSkipListMap
|
||||||
import kotlin.properties.ReadWriteProperty
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
import kotlin.reflect.full.isSubclassOf
|
import kotlin.reflect.full.isSubclassOf
|
||||||
|
|
||||||
@ -47,6 +46,7 @@ interface Config {
|
|||||||
operator fun set(key: String, value: Any)
|
operator fun set(key: String, value: Any)
|
||||||
operator fun get(key: String): Any?
|
operator fun get(key: String): Any?
|
||||||
fun exist(key: String): Boolean
|
fun exist(key: String): Boolean
|
||||||
|
fun setIfAbsent(key: String, value: Any)
|
||||||
fun asMap(): Map<String, Any>
|
fun asMap(): Map<String, Any>
|
||||||
fun save()
|
fun save()
|
||||||
|
|
||||||
@ -67,47 +67,109 @@ interface Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun File.loadAsConfig(): Config {
|
||||||
|
return Config.load(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 最简单的代理 */
|
||||||
|
inline operator fun <reified T : Any> Config.getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||||
|
return smartCast(property)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator fun <reified T : Any> Config.setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||||
|
this[property.name] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 带有默认值的代理 */
|
||||||
inline fun <reified T : Any> Config.withDefault(
|
inline fun <reified T : Any> Config.withDefault(
|
||||||
autoSave: Boolean = true,
|
noinline defaultValue: () -> T
|
||||||
crossinline defaultValue: () -> T
|
|
||||||
): ReadWriteProperty<Any, T> {
|
): ReadWriteProperty<Any, T> {
|
||||||
|
val default by lazy { defaultValue.invoke() }
|
||||||
return object : ReadWriteProperty<Any, T> {
|
return object : ReadWriteProperty<Any, T> {
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>): T {
|
override fun getValue(thisRef: Any, property: KProperty<*>): T {
|
||||||
if (!this@withDefault.exist(property.name)) {
|
if (this@withDefault.exist(property.name)) {//unsafe
|
||||||
return defaultValue.invoke()
|
return this@withDefault.smartCast(property)
|
||||||
}
|
}
|
||||||
return smartCast(property)
|
return default
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
|
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
|
||||||
this@withDefault[property.name] = value
|
this@withDefault[property.name] = value
|
||||||
if (autoSave) save()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("IMPLICIT_CAST_TO_ANY")
|
/* 带有默认值且如果为空会写入的代理 */
|
||||||
inline fun <reified T> Config.smartCast(property: KProperty<*>): T {
|
inline fun <reified T : Any> Config.withDefaultWrite(
|
||||||
return when (T::class) {
|
noinline defaultValue: () -> T
|
||||||
String::class -> this.getString(property.name)
|
): WithDefaultWriteLoader<T> {
|
||||||
Int::class -> this.getInt(property.name)
|
return WithDefaultWriteLoader(T::class, this, defaultValue, false)
|
||||||
Float::class -> this.getFloat(property.name)
|
}
|
||||||
Double::class -> this.getDouble(property.name)
|
|
||||||
Long::class -> this.getLong(property.name)
|
/* 带有默认值且如果为空会写入保存的代理 */
|
||||||
Boolean::class -> this.getBoolean(property.name)
|
inline fun <reified T : Any> Config.withDefaultWriteSave(
|
||||||
|
noinline defaultValue: () -> T
|
||||||
|
): WithDefaultWriteLoader<T> {
|
||||||
|
return WithDefaultWriteLoader(T::class, this, defaultValue, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
class WithDefaultWriteLoader<T : Any>(
|
||||||
|
private val _class: KClass<T>,
|
||||||
|
private val config: Config,
|
||||||
|
private val defaultValue: () -> T,
|
||||||
|
private val save: Boolean
|
||||||
|
) {
|
||||||
|
operator fun provideDelegate(
|
||||||
|
thisRef: Any,
|
||||||
|
prop: KProperty<*>
|
||||||
|
): ReadWriteProperty<Any, T> {
|
||||||
|
val defaultValue by lazy { defaultValue.invoke() }
|
||||||
|
config.setIfAbsent(prop.name, defaultValue)
|
||||||
|
if (save) {
|
||||||
|
config.save()
|
||||||
|
}
|
||||||
|
return object : ReadWriteProperty<Any, T> {
|
||||||
|
override fun getValue(thisRef: Any, property: KProperty<*>): T {
|
||||||
|
if (config.exist(property.name)) {//unsafe
|
||||||
|
return config._smartCast(property.name, _class)
|
||||||
|
}
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
|
||||||
|
config[property.name] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : Any> Config.smartCast(property: KProperty<*>): T {
|
||||||
|
return _smartCast(property.name, T::class)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("IMPLICIT_CAST_TO_ANY", "UNCHECKED_CAST")
|
||||||
|
fun <T : Any> Config._smartCast(propertyName: String, _class: KClass<T>): T {
|
||||||
|
return when (_class) {
|
||||||
|
String::class -> this.getString(propertyName)
|
||||||
|
Int::class -> this.getInt(propertyName)
|
||||||
|
Float::class -> this.getFloat(propertyName)
|
||||||
|
Double::class -> this.getDouble(propertyName)
|
||||||
|
Long::class -> this.getLong(propertyName)
|
||||||
|
Boolean::class -> this.getBoolean(propertyName)
|
||||||
else -> when {
|
else -> when {
|
||||||
T::class.isSubclassOf(ConfigSection::class) -> this.getConfigSection(property.name)
|
_class.isSubclassOf(ConfigSection::class) -> this.getConfigSection(propertyName)
|
||||||
T::class == List::class || T::class == MutableList::class -> {
|
_class == List::class || _class == MutableList::class -> {
|
||||||
val list = this.getList(property.name)
|
val list = this.getList(propertyName)
|
||||||
return if (list.isEmpty()) {
|
return if (list.isEmpty()) {
|
||||||
list
|
list
|
||||||
} else {
|
} else {
|
||||||
when (list[0]!!::class) {
|
when (list[0]!!::class) {
|
||||||
String::class -> getStringList(property.name)
|
String::class -> getStringList(propertyName)
|
||||||
Int::class -> getIntList(property.name)
|
Int::class -> getIntList(propertyName)
|
||||||
Float::class -> getFloatList(property.name)
|
Float::class -> getFloatList(propertyName)
|
||||||
Double::class -> getDoubleList(property.name)
|
Double::class -> getDoubleList(propertyName)
|
||||||
Long::class -> getLongList(property.name)
|
Long::class -> getLongList(propertyName)
|
||||||
else -> {
|
else -> {
|
||||||
error("unsupported type")
|
error("unsupported type")
|
||||||
}
|
}
|
||||||
@ -121,14 +183,6 @@ inline fun <reified T> Config.smartCast(property: KProperty<*>): T {
|
|||||||
} as T
|
} as T
|
||||||
}
|
}
|
||||||
|
|
||||||
inline operator fun <reified T> Config.getValue(thisRef: Any?, property: KProperty<*>): T {
|
|
||||||
return smartCast(property)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline operator fun <reified T> Config.setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
|
||||||
this[property.name] = value!!
|
|
||||||
this.save()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
interface ConfigSection : Config {
|
interface ConfigSection : Config {
|
||||||
@ -187,12 +241,16 @@ interface ConfigSection : Config {
|
|||||||
override fun exist(key: String): Boolean {
|
override fun exist(key: String): Boolean {
|
||||||
return get(key) != null
|
return get(key) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setIfAbsent(key: String, value: Any) {
|
||||||
|
if (!exist(key)) set(key, value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
open class ConfigSectionImpl() : ConcurrentHashMap<String, Any>(), ConfigSection {
|
open class ConfigSectionImpl() : ConcurrentHashMap<String, Any>(), ConfigSection {
|
||||||
override fun set(key: String, value: Any) {
|
override fun set(key: String, value: Any) {
|
||||||
this.put(key, value)
|
super.put(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun get(key: String): Any? {
|
override operator fun get(key: String): Any? {
|
||||||
@ -210,6 +268,10 @@ open class ConfigSectionImpl() : ConcurrentHashMap<String, Any>(), ConfigSection
|
|||||||
override fun save() {
|
override fun save() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setIfAbsent(key: String, value: Any) {
|
||||||
|
this.putIfAbsent(key, value)//atomic
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -255,26 +317,15 @@ class JsonConfig internal constructor(file: File) : FileConfigImpl(file) {
|
|||||||
if (content.isEmpty() || content.isBlank() || content == "{}") {
|
if (content.isEmpty() || content.isBlank() || content == "{}") {
|
||||||
return ConfigSectionImpl()
|
return ConfigSectionImpl()
|
||||||
}
|
}
|
||||||
val section = JSON.parseObject(
|
return JSON.parseObject<ConfigSectionImpl>(
|
||||||
content,
|
content,
|
||||||
object : TypeReference<ConfigSectionImpl>() {},
|
object : TypeReference<ConfigSectionImpl>() {},
|
||||||
Feature.OrderedField
|
Feature.OrderedField
|
||||||
)
|
)
|
||||||
return section
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UnstableDefault
|
@UnstableDefault
|
||||||
override fun serialize(config: ConfigSection): String {
|
override fun serialize(config: ConfigSection): String {
|
||||||
return JSONObject.toJSONString(config)
|
return JSONObject.toJSONString(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class AnySerializer(override val descriptor: SerialDescriptor) : KSerializer<Any> {
|
|
||||||
override fun deserialize(decoder: Decoder): Any {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, obj: Any) {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user