跳到主要内容

持久性数据容器

持久性数据容器(PDC)是一个用于存储和检索数据的API。它允许插件将数据附加到游戏对象上, 这些数据会在服务器重启后保持不变。

数据持有者

PDC可以附加到实现PersistentDataHolder接口的任何对象上。 这包括:

  • 实体
  • 物品栈
  • 方块状态
  • 世界
  • 区块
  • 结构

使用PDC

要使用PDC,你需要:

  1. 获取一个PersistentDataContainer
  2. 创建一个NamespacedKey
  3. 使用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()。你需要提供:

  1. 一个NamespacedKey
  2. 一个PersistentDataType
  3. 要存储的值
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()。你需要提供:

  1. 一个NamespacedKey
  2. 一个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 - 一个嵌套的PDC
  • TAG_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...
}
}