使用示例
# 设置头颅皮肤
# 我们会使用 这个头颅 (opens new window) 作为示例
// 这个是从上面提到的网站下面的 base64 材质值
final String textureValue = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTQyY2M5MjAzYzkwYjg5YmRhYzFkZjI4NDE2NzI2NmI5NTNkZmViZjNjNDY5MGE3Y2QwYjE1NzkxYTYyZTU4MiJ9fX0=";
// 创建 ItemStack
// 对于 Minecraft 1.12.2 及以下版本
final ItemStack item = new ItemStack(Material.SKULL_ITEM);
item.setDurability((short) 3);
// 对于 Minecraft 1.13 或更高版本
final ItemStack item = new ItemStack(Material.PLAYER_HEAD);
// 应用 NBT
// 对于 Minecraft 1.20.4 及以下版本
NBT.modify(item, nbt -> {
ReadWriteNBT skullOwnerCompound = nbt.getOrCreateCompound("SkullOwner");
// 头颅所有者的 UUID。注意,有相同 UUID 但不同材质的头颅将会有不确定的行为,并且只有一个材质会加载。
// 它们会共用材质。要避免这个限制,推荐使用随机的 UUID。
skullOwnerCompound.setUUID("Id", UUID.randomUUID());
skullOwnerCompound.getOrCreateCompound("Properties")
.getCompoundList("textures")
.addCompound()
.setString("Value", textureValue);
});
// 对于 Minecraft 1.20.5+ 的解决方案
NBT.modifyComponents(item, nbt -> {
ReadWriteNBT profileNbt = nbt.getOrCreateCompound("minecraft:profile");
profileNbt.setUUID("id", uuid);
ReadWriteNBT propertiesNbt = profileNbt.getCompoundList("properties").addCompound();
propertiesNbt.setString("name", "textures");
propertiesNbt.setString("value", textureValue);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
注意
如果你在使用 1.12.2+ 的 Paper API,你可以使用以下代码来创建有材质的头颅
SkullMeta meta = (SkullMeta) item.getItemMeta();
PlayerProfile playerProfile = Bukkit.createProfile(uuid);
playerProfile.setProperty(new ProfileProperty("textures", textureValue));
meta.setPlayerProfile(playerProfile);
// 在 1.17+ 你也可以使用 item.editMeta(SkullMeta.class, meta -> {});
item.setItemMeta(meta);
1
2
3
4
5
6
2
3
4
5
6
# 可以捡起物品,且能造成 0.5 心伤害的僵尸
这个代码仅作为一个参考,不同版本之间的 NBT 结构可能有变动。
Zombie zombie = location.getWorld().spawn(location, Zombie.class);
String attributeName = "minecraft:generic.attack_damage"; // 或者 generic.attackDamage 在 1.16 之前
double damageValue = 0.5;
// 更改原版数据
NBT.modify(zombie, nbt -> {
nbt.setBoolean("CanPickUpLoot", true);
ReadWriteNBTCompoundList list = nbt.getCompoundList("Attributes");
// 检查僵尸是否已经设置这个属性了,如果设置了,修改它
for (ReadWriteNBT listEntryNbt : list) {
if (!listEntryNbt.getString("Name").equals(attributeName)) continue;
listEntryNbt.setDouble("Base", damageValue);
return;
}
// 如果没有这个属性,添加进去
ReadWriteNBT listEntryNbt = list.addCompound();
listEntryNbt.setString("Name", attributeName);
listEntryNbt.setDouble("Base", damageValue);
});
// 修改自定义数据
NBT.modifyPersistentData(zombie, nbt -> {
// 标记这个僵尸是我们自定义的那个
nbt.setBoolean("custom_zombie", true);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 读取世界数据
// 获取主世界文件夹
File worldDataFolder = Bukkit.getWorlds().getFirst().getWorldFolder();
// 读取存档数据
NBTFileHandle levelNbtFile = NBT.getFileHandle(new File(worldDataFolder, "level.dat"));
// 获取世界名
String worldName = levelNbtFile.resolveOrNull("Data.LevelName", String.class);
// 读取一些玩家的数据
UUID playerUuid;
File playerFile = new File(worldDataFolder, "playerdata/" + playerUuid + ".dat");
if (!playerFile.exists()) {
// 没有提供的 UUID 对应离线玩家的数据
return;
}
NBTFileHandle playerNbtFile = NBT.getFileHandle(playerFile);
// 更改玩家血量
float health = playerNbtFile.getFloat("Health");
playerNbtFile.setFloat("Health", health + 5);
// 一旦完成,保存文件
playerNbtFile.save();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
上次更新: 2025/06/16, 04:01:40