mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-09 09:50:16 +08:00
demo plugin and read-only config
This commit is contained in:
parent
971d7e182f
commit
108183daad
@ -17,8 +17,11 @@ import com.moandjiezana.toml.Toml
|
||||
import com.moandjiezana.toml.TomlWriter
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UnstableDefault
|
||||
import net.mamoe.mirai.utils.io.encodeToString
|
||||
import org.yaml.snakeyaml.Yaml
|
||||
import tornadofx.c
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.collections.LinkedHashMap
|
||||
@ -69,6 +72,9 @@ interface Config {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* create a read-write config
|
||||
* */
|
||||
fun load(file: File): Config {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile()
|
||||
@ -86,6 +92,32 @@ interface Config {
|
||||
else -> error("Unsupported file config type ${file.extension.toLowerCase()}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a read-only config
|
||||
*/
|
||||
fun load(content: String, type: String): Config {
|
||||
return when (type.toLowerCase()) {
|
||||
"json" -> JsonConfig(content)
|
||||
"yml" -> YamlConfig(content)
|
||||
"yaml" -> YamlConfig(content)
|
||||
"mirai" -> YamlConfig(content)
|
||||
"ini" -> TomlConfig(content)
|
||||
"toml" -> TomlConfig(content)
|
||||
"properties" -> TomlConfig(content)
|
||||
"property" -> TomlConfig(content)
|
||||
"data" -> TomlConfig(content)
|
||||
else -> error("Unsupported file config type $content")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a read-only config
|
||||
*/
|
||||
fun load(inputStream: InputStream, type: String): Config {
|
||||
return load(inputStream.readBytes().encodeToString(), type)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,14 +395,23 @@ interface FileConfig : Config {
|
||||
|
||||
|
||||
abstract class FileConfigImpl internal constructor(
|
||||
private val file: File
|
||||
private val rawContent: String
|
||||
) : FileConfig,
|
||||
ConfigSection {
|
||||
|
||||
private val content by lazy {
|
||||
deserialize(file.readText())
|
||||
internal var file: File? = null
|
||||
|
||||
|
||||
constructor(file: File) : this(file.readText()) {
|
||||
this.file = file
|
||||
}
|
||||
|
||||
|
||||
private val content by lazy {
|
||||
deserialize(rawContent)
|
||||
}
|
||||
|
||||
|
||||
override val size: Int get() = content.size
|
||||
override val entries: MutableSet<MutableMap.MutableEntry<String, Any>> get() = content.entries
|
||||
override val keys: MutableSet<String> get() = content.keys
|
||||
@ -384,12 +425,17 @@ abstract class FileConfigImpl internal constructor(
|
||||
override fun remove(key: String): Any? = content.remove(key)
|
||||
|
||||
override fun save() {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile()
|
||||
if (isReadOnly()) {
|
||||
error("Config is readonly")
|
||||
}
|
||||
file.writeText(serialize(content))
|
||||
if (!((file?.exists())!!)) {
|
||||
file?.createNewFile()
|
||||
}
|
||||
file?.writeText(serialize(content))
|
||||
}
|
||||
|
||||
fun isReadOnly() = file == null
|
||||
|
||||
override fun contains(key: String): Boolean {
|
||||
return content.contains(key)
|
||||
}
|
||||
@ -409,8 +455,12 @@ abstract class FileConfigImpl internal constructor(
|
||||
}
|
||||
|
||||
class JsonConfig internal constructor(
|
||||
file: File
|
||||
) : FileConfigImpl(file) {
|
||||
content: String
|
||||
) : FileConfigImpl(content) {
|
||||
constructor(file: File) : this(file.readText()) {
|
||||
this.file = file
|
||||
}
|
||||
|
||||
@UnstableDefault
|
||||
override fun deserialize(content: String): ConfigSection {
|
||||
if (content.isEmpty() || content.isBlank() || content == "{}") {
|
||||
@ -429,7 +479,11 @@ class JsonConfig internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
class YamlConfig internal constructor(file: File) : FileConfigImpl(file) {
|
||||
class YamlConfig internal constructor(content: String) : FileConfigImpl(content) {
|
||||
constructor(file: File) : this(file.readText()) {
|
||||
this.file = file
|
||||
}
|
||||
|
||||
override fun deserialize(content: String): ConfigSection {
|
||||
if (content.isEmpty() || content.isBlank()) {
|
||||
return ConfigSectionImpl()
|
||||
@ -447,7 +501,11 @@ class YamlConfig internal constructor(file: File) : FileConfigImpl(file) {
|
||||
|
||||
}
|
||||
|
||||
class TomlConfig internal constructor(file: File) : FileConfigImpl(file) {
|
||||
class TomlConfig internal constructor(content: String) : FileConfigImpl(content) {
|
||||
constructor(file: File) : this(file.readText()) {
|
||||
this.file = file
|
||||
}
|
||||
|
||||
override fun deserialize(content: String): ConfigSection {
|
||||
if (content.isEmpty() || content.isBlank()) {
|
||||
return ConfigSectionImpl()
|
||||
|
@ -17,6 +17,7 @@ import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.SimpleLogger
|
||||
import net.mamoe.mirai.utils.io.encodeToString
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.net.URL
|
||||
import java.net.URLClassLoader
|
||||
import java.util.jar.JarFile
|
||||
@ -91,6 +92,13 @@ abstract class PluginBase(coroutineContext: CoroutineContext) : CoroutineScope {
|
||||
val logger: MiraiLogger by lazy {
|
||||
DefaultLogger(pluginDescription.name)
|
||||
}
|
||||
|
||||
fun getResources(fileName: String): InputStream? {
|
||||
return PluginManager.getFileInJarByName(
|
||||
this.pluginDescription.name,
|
||||
fileName
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class PluginDescription(
|
||||
@ -325,6 +333,47 @@ object PluginManager {
|
||||
it.disable(throwable)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据插件名字找Jar的文件
|
||||
* null => 没找到
|
||||
*/
|
||||
fun getJarPath(pluginName: String): File? {
|
||||
File(pluginsPath).listFiles()?.forEach { file ->
|
||||
if (file != null && file.extension == "jar") {
|
||||
val jar = JarFile(file)
|
||||
val pluginYml =
|
||||
jar.entries().asSequence().filter { it.name.toLowerCase().contains("plugin.yml") }.firstOrNull()
|
||||
if (pluginYml != null) {
|
||||
val description =
|
||||
PluginDescription.readFromContent(
|
||||
URL("jar:file:" + file.absoluteFile + "!/" + pluginYml.name).openConnection().inputStream.use {
|
||||
it.readBytes().encodeToString()
|
||||
})
|
||||
if (description.name.toLowerCase() == pluginName.toLowerCase()) {
|
||||
return file
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据插件名字找Jar resources中的文件
|
||||
* null => 没找到
|
||||
*/
|
||||
fun getFileInJarByName(pluginName: String, toFind: String): InputStream? {
|
||||
val jarFile = getJarPath(pluginName)
|
||||
if (jarFile == null) {
|
||||
return null
|
||||
}
|
||||
val jar = JarFile(jarFile)
|
||||
val toFindFile =
|
||||
jar.entries().asSequence().filter { it.name == toFind }.firstOrNull() ?: return null
|
||||
return URL("jar:file:" + jarFile.absoluteFile + "!/" + toFindFile.name).openConnection().inputStream
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,17 +12,17 @@ package net.mamoe.mirai.imageplugin
|
||||
import kotlinx.coroutines.*
|
||||
import net.mamoe.mirai.console.plugins.Config
|
||||
import net.mamoe.mirai.console.plugins.ConfigSection
|
||||
import net.mamoe.mirai.console.plugins.PluginBase
|
||||
import net.mamoe.mirai.contact.Contact
|
||||
import net.mamoe.mirai.event.events.BotOnlineEvent
|
||||
import net.mamoe.mirai.event.subscribeAlways
|
||||
import net.mamoe.mirai.event.subscribeMessages
|
||||
import net.mamoe.mirai.console.plugins.PluginBase
|
||||
import net.mamoe.mirai.contact.Contact
|
||||
import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.message.uploadAsImage
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import org.jsoup.Jsoup
|
||||
import java.io.File
|
||||
import kotlin.random.Random
|
||||
import java.net.URL
|
||||
|
||||
class ImageSenderMain : PluginBase() {
|
||||
|
||||
@ -60,7 +60,6 @@ class ImageSenderMain : PluginBase() {
|
||||
reply(e.message ?: "unknown error")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,16 +83,21 @@ class ImageSenderMain : PluginBase() {
|
||||
|
||||
override fun onLoad() {
|
||||
logger.info("loading local image data")
|
||||
|
||||
try {
|
||||
images = Config.load(this.javaClass.classLoader.getResource("data.yml")!!.path!!)
|
||||
images = Config.load(getResources(fileName = "data.yml")!!, "yml")
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
logger.info("无法加载本地图片")
|
||||
}
|
||||
logger.info("本地图片版本" + images.getString("version"))
|
||||
logger.info("Normal * " + images.getList("normal").size)
|
||||
logger.info("R18 * " + images.getList("R18").size)
|
||||
r18 = images.getConfigSectionList("R18")
|
||||
normal = images.getConfigSectionList("normal")
|
||||
logger.info("Normal * " + normal.size)
|
||||
logger.info("R18 * " + r18.size)
|
||||
}
|
||||
|
||||
|
||||
override fun onDisable() {
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user