8-3 创建和初始化项目
创建项目并添加依赖
新建项目并正确地修改相应的文件,然后在 build.gradle.kts 的 dependencies 块中添加 Java TOTP 作为依赖:
implementation("dev.samstevens.totp:totp:1.7.1")
完成后记得要重新导入 Gradle 项目。
plugin.yml 内容如下:
name: TOTP
author: skjsjhb
description: TOTP 2FA plugin for your server.
website: https://bpd.skjsjhb.moe/docs/the-tutorial/totp/sketch
main: Main
version: 1.0
api-version: 1.21
commands:
totp:
description: Enable TOTP or authenticate with TOTP code.
我们将使用同一个 /totp 命令来处理启用 TOTP 和验证 TOTP两种操作,如果用户提供了验证码,那就是验证,否则就是启用。
config.yml 内容如下:
# 插件是否启用
enabled: true
# 验证器中显示的颁发者
issuer: Minecraft Server
TOTP 验证器中会显示每个密钥的颁发者,我们允许管理员通过修改 issuer 的值来自定义该名称:

这可以便于用户区分密钥的来源。
创建监听器
新建文件并创建 TOTPListener 监听器:
class TOTPListener(private val plugin: Main): Listener {
// ...
}
实际上,在已经做了这么多个项目后,你完全可以自由发挥,如果觉得都放在 Main.kt 里更方便,那也完全可以这么做,另外你也可以给监听器类取更好听的名字。你了解的知识越多,编写的代码就越不需要拘泥于定式。
和以前不同的是,我们通过构造函数传递插件对象,而不是配置文件。这是因为我们想要在 TOTPListener 中使用插件的 dataFolder 属性,以便于稍后读写存储着密钥的文件。由于无论是 config 还是 dataFolder 都是插件对象的属性,因此直接传递插件对象更为简单。
我们顺便也把 issuer 的值提取出来:
private val issuer = plugin.config.getString("issuer", "Minecraft Server")!!
使用密钥文件
接下来我们创建密钥文件对象,我们计划使用 secrets.yml 来存储密钥,因此要将它提供给 File 的构造函数:
private val secretsFile = File(plugin.dataFolder, "secrets.yml")
并且将其中的内容读取出来:
private val secretsData = YamlConfiguration.loadConfiguration(secretsFile)
/**
* 从指定的文件中读取 YAML 格式的数据。
* 如果无法读取或解析文件,则返回空白内容。
*/
fun loadConfiguration(f: File): YamlConfiguration
YamlConfiguration.loadConfiguration 尝试从指定的文件中读取 YAML 数据,读取到的数据和配置文件是一样的,可以通过一系列 getXXX 进行操作。
由于这个文件是我们自行创建和读取的,因此在服务器关闭时需要保存,和上一章中一样,我们在 TOTPListener 中添加一个方法,这样就可以在 Main.onDisable 中使用它:
fun saveSecrets() {
secretsData.save(secretsFile)
}
/**
* 将 YAML 数据对象的内容存入指定文件。
*/
fun save(f: File): Unit