持久性数据容器
持久性数据容器(PDC)是一个用于存储和检索数据的API。它允许插件将数据附加到游戏对象上, 这些数据会在服务器重启后保持不变。
数据持有者
PDC可以附加到实现PersistentDataHolder接口的任何对象上。 这包括:
- 实体
- 物品栈
- 方块状态
- 世界
- 区块
- 结构
使用PDC
要使用PDC,你需要:
- 获取一个PersistentDataContainer
- 创建一个NamespacedKey
- 使用PersistentDataType存储或检索数据
获取容器
要获取PDC,调用PersistentDataHolder#getPersistentDataContainer()。
TestPlugin.java
@Override
public void onEnable() {
// 获取一个实体的PDC
Entity entity = ...;
PersistentDataContainer entityContainer = entity.getPersistentDataContainer();
// 获取一个物品栈的PDC
ItemStack item = ...;
ItemMeta meta = item.getItemMeta();
PersistentDataContainer itemContainer = meta.getPersistentDataContainer();
// 记得在修改后保存meta!
item.setItemMeta(meta);
}
创建键
要创建一个NamespacedKey,你需要一个命名空间和一个键。命名空间通常是你的插件ID(小写)。
TestPlugin.java
@Override
public void onEnable() {
// 使用插件实例创建键
NamespacedKey key = new NamespacedKey(this, "my-key");
// 或者使用字符串创建键
NamespacedKey key2 = new NamespacedKey("my-plugin", "my-key");
}
存储数据
要存储数据,使用PersistentDataContainer#set()。你需要提供:
- 一个
NamespacedKey - 一个
PersistentDataType - 要存储的值
TestPlugin.java
@Override
public void onEnable() {
Entity entity = ...;
PersistentDataContainer container = entity.getPersistentDataContainer();
NamespacedKey key = new NamespacedKey(this, "my-key");
// 存储一个整数
container.set(key, PersistentDataType.INTEGER, 123);
// 存储一个字符串
container.set(key, PersistentDataType.STRING, "hello world");
// 存储一个布尔值
container.set(key, PersistentDataType.BOOLEAN, true);
}
检索数据
要检索数据,使用PersistentDataContainer#get()。你需要提供:
- 一个
NamespacedKey - 一个
PersistentDataType
TestPlugin.java
@Override
public void onEnable() {
Entity entity = ...;
PersistentDataContainer container = entity.getPersistentDataContainer();
NamespacedKey key = new NamespacedKey(this, "my-key");
// 获取一个整数
Integer value = container.get(key, PersistentDataType.INTEGER);
if (value != null) {
// 使用值...
}
// 获取一个字符串
String string = container.get(key, PersistentDataType.STRING);
if (string != null) {
// 使用字符串...
}
// 获取一个布尔值
Boolean bool = container.get(key, PersistentDataType.BOOLEAN);
if (bool != null) {
// 使用布尔值...
}
}
检查数据
要检查容器中是否存在某个键,使用PersistentDataContainer#has()。
TestPlugin.java
@Override
public void onEnable() {
Entity entity = ...;
PersistentDataContainer container = entity.getPersistentDataContainer();
NamespacedKey key = new NamespacedKey(this, "my-key");
if (container.has(key, PersistentDataType.INTEGER)) {
// 容器中存在一个整数值
}
}
删除数据
要删除数据,使用PersistentDataContainer#remove()。
TestPlugin.java
@Override
public void onEnable() {
Entity entity = ...;
PersistentDataContainer container = entity.getPersistentDataContainer();
NamespacedKey key = new NamespacedKey(this, "my-key");
container.remove(key);
}
数据类型
PDC支持以下数据类型:
BYTE- 一个字节SHORT- 一个短整数INTEGER- 一个整数LONG- 一个长整数FLOAT- 一个浮点数DOUBLE- 一个双精度浮点数STRING- 一个字符串BYTE_ARRAY- 一个字节数组INTEGER_ARRAY- 一个整数数组LONG_ARRAY- 一个长整数数组TAG_CONTAINER- 一个嵌套的PDCTAG_CONTAINER_ARRAY- 一个PDC数组
自定义数据类型
你可以通过实现PersistentDataType接口来创建自定义数据类型。
UUIDDataType.java
public class UUIDDataType implements PersistentDataType<byte[], UUID> {
@Override
public Class<byte[]> getPrimitiveType() {
return byte[].class;
}
@Override
public Class<UUID> getComplexType() {
return UUID.class;
}
@Override
public byte[] toPrimitive(UUID complex, PersistentDataAdapterContext context) {
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(complex.getMostSignificantBits());
bb.putLong(complex.getLeastSignificantBits());
return bb.array();
}
@Override
public UUID fromPrimitive(byte[] primitive, PersistentDataAdapterContext context) {
ByteBuffer bb = ByteBuffer.wrap(primitive);
long firstLong = bb.getLong();
long secondLong = bb.getLong();
return new UUID(firstLong, secondLong);
}
}
然后你可以这样使用它:
TestPlugin.java
public static final PersistentDataType<byte[], UUID> UUID = new UUIDDataType();
@Override
public void onEnable() {
Entity entity = ...;
PersistentDataContainer container = entity.getPersistentDataContainer();
NamespacedKey key = new NamespacedKey(this, "my-uuid");
// 存储一个UUID
container.set(key, UUID, java.util.UUID.randomUUID());
// 获取一个UUID
java.util.UUID value = container.get(key, UUID);
if (value != null) {
// 使用UUID...
}
}