2.6
This commit is contained in:
203
docs/mcguide/28-电脑网络游戏/课程4:常见第三方库教程/31-TabooLib/1-基础技术/5-配置文件.md
Normal file
203
docs/mcguide/28-电脑网络游戏/课程4:常见第三方库教程/31-TabooLib/1-基础技术/5-配置文件.md
Normal file
@@ -0,0 +1,203 @@
|
||||
---
|
||||
front:
|
||||
hard: 入门
|
||||
time: 20分钟
|
||||
---
|
||||
|
||||
|
||||
# 配置文件
|
||||
|
||||
## 介绍
|
||||
EventBus 是 Bukkit开发核心内容之一
|
||||
|
||||
## 监听事件
|
||||
通常情况下也就能使用到此功能
|
||||
比如我们要监听玩家进入游戏的事件 应该如何书写?
|
||||
|
||||
```kotlin
|
||||
@SubscribeEvent
|
||||
fun hello(event: PlayerJoinEvent) {
|
||||
event.player.sendMessage("Hello, ${event.player.name}")
|
||||
}
|
||||
```
|
||||
> 和原版的监听器相似 都是在方法上 进行标记 但是我们不需要去主类注册
|
||||
|
||||
## 注册事件
|
||||
```kotlin
|
||||
@Config("lib/test.yml")
|
||||
lateinit var config: ConfigFile
|
||||
```
|
||||
|
||||
那设置配置文件了如何保存呢?
|
||||
```kotlin
|
||||
|
||||
fun test() {
|
||||
config.set("hello.hello", "value")
|
||||
// 等价于
|
||||
config["hello.hello"] = "value"
|
||||
config.saveToFile()
|
||||
}
|
||||
```
|
||||
|
||||
## 本地数据文件
|
||||
`createLocal( path, saveTime, type )`
|
||||
比如某些数据,我想通过本地配置文件保存
|
||||
方法参数:
|
||||
1. path - 文件路径
|
||||
2. saveTime - 自动保存时间
|
||||
3. type - 文件类型
|
||||
|
||||
```kotlin
|
||||
fun test() {
|
||||
val test = createLocal("test.yml")
|
||||
test[playerName, number]
|
||||
// 不需要写保存 会自动保存 当然也可以手动保存
|
||||
// createLocal.saveToFile()
|
||||
}
|
||||
```
|
||||
|
||||
## 创建配置文件
|
||||
如果不想让TabooLib帮助你管理
|
||||
比如你想自己在resources里手动创建好一个配置文件,然后在里面预设好配置这个配置文件
|
||||
应该怎么写?
|
||||
|
||||
```kotlin
|
||||
fun test() {
|
||||
val file = newFile(getDataFolder(), "path.yml", create = true)
|
||||
val loadFromFile = Configuration.loadFromFile(file, Type.YAML)
|
||||
}
|
||||
```
|
||||
|
||||
## 读取某个文件
|
||||
如果有一个 yaml 并不是你创建的或者是你创建了但是没有缓存应该如何读取呢?
|
||||
和创建方法相似但是我们不需要 create = true
|
||||
```kotlin
|
||||
fun test() {
|
||||
val file = newFile(getDataFolder(), "path.yml") ?: return
|
||||
val loadFromFile = Configuration.loadFromFile(file, Type.YAML)
|
||||
}
|
||||
```
|
||||
> 一个小 tip 给不会使用Kotlin的读者
|
||||
> 当你在一个变量后面写了 ?: return 的时候
|
||||
> 当这个变量为空的时候 就自动结束方法
|
||||
|
||||
|
||||
## 创建并写入File文本
|
||||
通常是在一些 序列化 的场景中使用
|
||||
```kotlin
|
||||
newFile(getDataFolder(), it.path, create = true).writeText(
|
||||
Yaml.encodeToString(ShopGoodsBaseData.serializer(), it),
|
||||
StandardCharsets.UTF_8
|
||||
)
|
||||
```
|
||||
|
||||
## 读取File文本
|
||||
通常在一些 反序列化 的场景中使用
|
||||
```kotlin
|
||||
fun loadData(file: File) {
|
||||
file.readText(StandardCharsets.UTF_8).let { text ->
|
||||
ShopManager.goods.add(
|
||||
Yaml.decodeFromString(ShopGoodsBaseData.serializer(), text)
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 根据File转化为配置文件
|
||||
有些时候 我们是只能拿到对象 拿不到文件的路径的(文件在内存中) 所以我们可以这样写
|
||||
```kotlin
|
||||
Configuration.loadFromFile(file, Type.YAML)
|
||||
```
|
||||
还有其他类似方法
|
||||
```kotlin
|
||||
fun loadFromFile(file: File, type: Type? = null, concurrent: Boolean = true)
|
||||
fun loadFromReader(reader: Reader, type: Type = Type.YAML, concurrent: Boolean = true)
|
||||
fun loadFromString(contents: String, type: Type = Type.YAML, concurrent: Boolean = true)
|
||||
fun loadFromInputStream(inputStream: InputStream, type: Type = Type.YAML, concurrent: Boolean = true)
|
||||
```
|
||||
|
||||
## 从Bukkit平台加载配置文件
|
||||
上文说到 不可以直接转换 需要通过一个方法转换
|
||||
只要来源的那个配置文件类 包含 `saveToString` 方法 且是标准的 就可以进行读取
|
||||
```kotlin
|
||||
fun loadFromOther(otherConfig: Any, type: Type = Type.YAML, concurrent: Boolean = true)
|
||||
```
|
||||
|
||||
## 实现文件更新监听
|
||||
通过 FileWatcher 自动识别文件是否更新
|
||||
如果有更新则自动重新获取File
|
||||
|
||||
```kotlin
|
||||
object FileListener {
|
||||
|
||||
private val listening = mutableSetOf<File>()
|
||||
|
||||
val watcher = FileWatcher.INSTANCE
|
||||
|
||||
fun listener(file: File, runnable: File.() -> Unit) {
|
||||
watcher.addSimpleListener(file, runnable)
|
||||
listening.add(file)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
listening.removeIf {
|
||||
val remove = !it.exists()
|
||||
if (remove) {
|
||||
watcher.removeListener(it)
|
||||
}
|
||||
remove
|
||||
}
|
||||
}
|
||||
|
||||
fun load() {
|
||||
val file = File(getDataFolder(), "config.yml")
|
||||
listener(file) {
|
||||
info("监听文件重载了")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 数据存储配置文件
|
||||
|
||||
如果想做本地数据存储 更快捷一点的 可以试试用这个方法
|
||||
```kotlin
|
||||
val database by lazy {
|
||||
createLocal("data/storage/data.yml", type = Type.YAML)
|
||||
}
|
||||
```
|
||||
这样使用的时候 就会创建这个配置文件 然后这个配置文件会自动保存
|
||||
所以 不可以手动更改配置文件
|
||||
|
||||
## 拓展 - 读取文件夹里的所有Yaml并加载
|
||||
```kotlin
|
||||
val read = ArrayList<Configuration>()
|
||||
|
||||
@Awake(LifeCycle.ENABLE)
|
||||
fun load() {
|
||||
read.clear()
|
||||
val file = newFolder(getDataFolder(), "marks", create = false)
|
||||
// 文件不存在则释放jar内的文件
|
||||
if (!file.exists()) {
|
||||
file.mkdirs()
|
||||
releaseResourceFile("marks/test.yml")
|
||||
}
|
||||
file.walk()
|
||||
.filter { it.isFile }
|
||||
.filter { it.extension == "yaml" || it.extension == "yml" }
|
||||
.forEach {
|
||||
read.add(Configuration.loadFromFile(it))
|
||||
}
|
||||
|
||||
releaseResourceFolderAndRead("marks/"){
|
||||
walk{
|
||||
read.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
> 注意,其中 **releaseResourceFolderAndRead** 这个方法并不是原生 `Taboolib` 自带的功能
|
||||
> 而是拓展库 [Arim](https://github.com/FxRayHughes/Arim) 里的方法
|
||||
> 这个是由社区开发者 枫溪、嘿鹰、 WhiteSoul、Saukiya、坏黑、Mical 编写的
|
||||
|
||||
Reference in New Issue
Block a user