开发者 API
介绍
LuckPerms 有一整套供开发者使用的 API,允许其他插件能够读取 LuckPerms 的数据,并简单地让 LuckPerms 与现有的插件与系统深入交互。
版本
API 使用的是语义化版本号,也就是说在不向前兼容的版本出现后,大版本号就会增加。至少你可以确保你的集成能在小版本间通用。
当前的 API 版本为 5.4
.
- LuckPerms 的 API 包为
net.luckperms.api
- JavaDocs 在标准 JavaDoc或 API 源码中均可查询。
更新日志
2.x
版本,API 首次发布。3.x
(2017 年 2 月 19 日)引入了不向前兼容的内容。[更新日志]4.x
(2017 年 11 月 7 日)引入了不向前兼容的内容。[更新日志]5.x
版本对 API 进行了完全重写。同时加入了桥接工具以维持与旧版本 API 的兼容性。
快速开始
将 LuckPerms 导入工程
API 成品可以在 Maven 中心的仓库中找到。
Maven
如果你正在使用 Maven,将这些内容添加至 POM 的 dependencies
部分即可。
<dependencies>
<dependency>
<groupId>net.luckperms</groupId>
<artifactId>api</artifactId>
<version>5.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
Gradle
若你正在使用 Gradle,请将这些内容放入你的构建脚本中。
Groovy DSL:
repositories {
mavenCentral()
}
dependencies {
compileOnly 'net.luckperms:api:5.4'
}
Kotlin DSL:
repositories {
mavenCentral()
}
dependencies {
compileOnly("net.luckperms:api:5.4")
}
手动
如果你想要将 API 依赖手动导入,你可以通过下列方式获取 jar:
- 进入
https://repo1.maven.org/maven2/net/luckperms/api/
- 选择你需要使用的版本
- 下载
api-x-x.jar
文件
获取 API 实例
API 示例的根为 LuckPerms
,在对 API 做任何事之前都需要先生成一个 API 实例。
它可以通过许多方式产生。
通过 Bukkit 的 ServicesManager
插件启用后,Bukkit 的 ServicesManager 会提供一个 LuckPerms
的实例。(只在 Bukkit 上有效!)
RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
if (provider != null) {
LuckPerms api = provider.getProvider();
}
通过 Sponge 的 ServicesManager
插件启用后,Sponge 的 ServicesManager 会提供一个 LuckPerms
的实例。(只在 Sponge 上有效!)
Optional<ProviderRegistration<LuckPerms>> provider = Sponge.getServiceManager().getRegistration(LuckPerms.class);
if (provider.isPresent()) {
LuckPerms api = provider.get().getProvider();
}
单例引入
插件启用后,LuckPermsProvider
会提供一个 LuckPerms
的实例。(全平台通用) **注意:**若 API 未载入,则这个方法会抛出一个 IllegalStateException
。
LuckPerms api = LuckPermsProvider.get();
实用信息
在你将 API 类添加至你的项目并生成了一个 LuckPerms
的实例之后,你可以开始使用 API 了。但是,在你进一步探索之前,我们希望你阅读并了解下面的信息。
线程安全
- 所有 LuckPerms 的示例都是对线程安全的。你可以以异步定时任务的形式(或从其他线程)与 API 实例交互
- 这也包括在 Bukkit/Bungee/Sponge 的权限查询方法。它们可以在 LuckPerms 用作权限插件时被安全地异步调用。
不可变性
- 在方法从 Java 集合框架返回类的情况下,除非另有说明,否则默认返回的方法始终不可变。(JavaDoc 有详细说明)
- 这表示你不能对已经返回的任何集合进行修改,且这些集合只是表示方法调用时返回数据的准确表示。
阻止操作
- 一些方法不对“主线程友好”,这表示它们如果从 Minecraft 服务器的主线程调用,服务器就会卡顿。
- 这是因为很多方法涉及了与文件系统或网络有关的 I/O 内容。
- 大多数情况下,方法均会返回 CompletableFuture。
- 这些对象一开始对某些用户而言可能非常复杂 —— 所以在尝试使用之前对它们有一个基本的了解很重要。
- 一般来讲,非常建议尽可能在与 API 交互时使用异步任务。一些方法不会返回异步对象,但仍可能会参与一些复杂的计算。
使用 CompletableFutures
这是一个简短的教程。若你想要了解更多,请阅读 JavaDoc 的 CompletableFuture 与 CompletionStage 部分。
为了便于解释,我们从 ActionLogger
类中拿出这个方法:
CompletableFuture<ActionLog> getLog();
在调用方法后,我们得到了一个 CompletableFuture<ActionLog>
—— 我们想要的对象是 ActionLog
。CompletableFuture
表示的是某个计算的结果(也就是说获取 ActionLog 的计算),并包含了获取 ActionLog
对象的方法。
如果我们的方法调用已经是异步(如果我们调用的方法来自于异步定时任务),那么我们就可以完全以异步对象将其去掉。
/*
Calling this method "requests" an ActionLog from the API.
However, it's unlikely that the log will be available immediately...
We need to wait for it to be supplied.
*/
CompletableFuture<ActionLog> logFuture = actionLogger.getLog();
/*
Since we're already on an async thread, it doesn't matter how long we
have to wait for the elusive Log to show up.
The #join method will block - and wait until the Log has been supplied,
and then return it.
If for whatever reason the process to obtain a ActionLog threw an exception,
this method will rethrow an the same exception wrapped in a CompletionException
*/
ActionLog log = logFuture.join();
其他方法是使用对 CompletableFuture 使用 #join
来注册一个回调,使得在 Log
产生时执行相应内容。
若我们需要在服务器主线程上使用实例,那么服务器主线程上会产生一个特殊的任务执行器传递给回调。
// Create an executor that will run our callback on the server thread.
Executor executor = runnable -> Bukkit.getScheduler().runTask(plugin, runnable);
// Register a callback with the future.
logFuture.whenCompleteAsync(new BiConsumer<ActionLog, Throwable>() { // can be reduced to a lambda, I've left it as an anonymous class for clarity
@Override
public void accept(ActionLog log, Throwable exception) {
if (exception != null) {
// There was some error whilst getting the log.
return;
}
// Use the log for something...
}
}, executor);
如果你不关心报错,那么这个还可以进一步简化:
logFuture.thenAcceptAsync(log -> { /* Use the log for something */ }, executor);
CompletableFuture 类一开始用起来可能会相当复杂(在 Java 中它还是个比较年轻的 API!),但它是封装异步计算的好方法,且在 Minecraft 的角度看来,它不会因等待超长的 I/O 调用而堵塞主线程。
异步事件&回调
- LuckPerms 的绝大部分工作都是在非服务器主线程上以异步任务的方式完成的。
- 在此前提下,还要去异步调用 LuckPerms 的想法会很好笑 —— 这表示,在没有错误的情况下,所有事件监听器都是异步调用的。
需要注意的是,Bukkit、Sponge 和 Minecraft 服务器的许多部分都不对线程友好,且应只从服务器线程方面与之交互。若你需要在 LuckPerms 的事件监听器或回调中使用来自 Bukkit 或 Sponge 的方法,你需要用计划表来执行操作。