Rtag 是一个高性能的 NBT 编辑库,它允许服务器管理员轻松安装,并为开发者提供了无需直接使用 NMS 即可操作物品、实体和方块 NBT 数据的能力,支持跨版本兼容和自定义对象存储。
服务器管理员指南
下载与安装
- 点击下载按钮,选择
rtag.jar文件。 - 将下载的
.jar文件放入服务器的plugins文件夹中。
要求
- Minecraft 版本: 至少需要 1.8.8,更低版本可能不兼容。
- Java 版本: 最低需要 Java 11。请更新您的 Java 版本,旧版 Minecraft 在 Java 11 上运行良好。
兼容性
- ✅ Bukkit
- ✅ Spigot
- ✅ Paper
- ✅ Paper with Mojang Mappings
- ✅ Folia
- ✅ 任何上述服务端(无需 craftbukkit 重定位,参见 [PaperMC 公告](PaperMC announce))
开发者指南
什么是 Rtag?
Rtag 提供了一种简单的方法来编辑 NBT 标签,无需使用 NMS,并避免了对大型服务器的性能影响。它是完全可嵌入的,你可以直接将 Rtag 集成到你的插件中。更多详细信息,请访问 [Wiki 页面](the wiki page)。
Rtag 可以将任何 Java 对象转换为 NBT 标签,反之亦然。
基础用法示例
// 使用物品
RtagItem tag = new RtagItem(item);
// 使用实体
RtagEntity tag = new RtagEntity(entity);
// 使用方块
RtagBlock tag = new RtagBlock(block);
// --- 设置值
// 在路径 "display.Name" 设置值 "Custom Text"
tag.set("Custom Text", "display", "Name");
// 或在路径 "someKey" 设置一个整数
tag.set(40, "someKey");
// 支持任何类型的对象,如 MyObject
MyObject myobject = new MyObject();
tag.set(myobject, "any", "path");
// 合并值到标签
tag.merge(Map.of("asd", 123, "someKey", 41), true);
// 可以添加列表
tag.set(new ArrayList(), "list", "path");
// 并向列表中添加值
tag.add((short) 3, "list", "path");
// 或替换现有列表的值
tag.set((short) 5, "list", "path", 0); // 索引 0
// --- 获取值
// 从路径 "display.Name" 获取值
String name = tag.get("display", "Name");
// 安全地从路径 "someKey" 获取值,默认为 -1
int intValue = tag.getOptional("someKey").or(-1);
int sameValue = tag.getOptional("someKey").asInt(-1); // 此方法尝试将任何类型转换为 int
// 显式获取自定义对象
MyObject sameobject = tag.getOptional("any", "path").as(MyObject.class);
// 获取列表
List<Short> list = tag.get("list", "path");
// 从索引获取列表值
short listValue = tag.get("list", "path", 0); // 索引 0
// 获取整个对象标签作为 Java 对象的 Map
Map<String, Object> map = tag.get();
// --- 将更改加载到对象
// 将更改加载到原始对象
tag.load();
// RtagItem 可以选择创建加载了更改的物品副本
ItemStack itemCopy = tag.loadCopy();
// --- 如果原始对象被编辑,则更新当前标签
tag.update();获取 Rtag
你可以通过以下构建工具将 Rtag 添加到你的项目中。
Gradle (Groovy)
在 `build.gradle` 中添加
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
compileOnly 'com.saicone.rtag:rtag:VERSION'
// 其他模块
compileOnly 'com.saicone.rtag:rtag-block:VERSION'
compileOnly 'com.saicone.rtag:rtag-entity:VERSION'
compileOnly 'com.saicone.rtag:rtag-item:VERSION'
}Gradle (Kotlin)
在 build.gradle.kts 中添加:
repositories {
maven("https://jitpack.io")
}
dependencies {
compileOnly("com.saicone.rtag:rtag:VERSION")
// 其他模块
compileOnly("com.saicone.rtag:rtag-block:VERSION")
compileOnly("com.saicone.rtag:rtag-entity:VERSION")
compileOnly("com.saicone.rtag:rtag-item:VERSION")
}Maven
在 `pom.xml` 中添加
<repositories>
<repository>
<id>Jitpack</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.saicone.rtag</groupId>
<artifactId>rtag</artifactId>
<version>VERSION</version>
<scope>provided</scope>
</dependency>
<!-- 其他模块 -->
<dependency>
<groupId>com.saicone.rtag</groupId>
<artifactId>rtag-block</artifactId>
<version>VERSION</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.saicone.rtag</groupId>
<artifactId>rtag-entity</artifactId>
<version>VERSION</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.saicone.rtag</groupId>
<artifactId>rtag-item</artifactId>
<version>VERSION</version>
<scope>provided</scope>
</dependency>
</dependencies>核心特性
1️⃣ 易于理解
你无需成为 NBT 标签专家,通过简单的方法即可设置和获取普通的 Java 对象。
Rtag rtag = new Rtag();
rtag.set(compound, "Normal string", "CustomTagPath");
String string = rtag.get(compound, "CustomTagPath");主要的 RtagEditor 实例提供了使标签编辑更简单的方法。
RtagItem tag = new RtagItem(item);
tag.setUnbreakable(true);
tag.setRepairCost(20);
int level = tag.getEnchantmentLevel("unbreaking"); // 附魔枚举、名称或ID
RtagEntity tag = new RtagEntity(entity);
tag.setAttributeBase("generic.attackDamage", 0.5);
RtagBlock tag = new RtagBlock(block);
tag.setCustomName("§eColored name");你可以在 RtagEditor 实例内部使用函数编辑对象,并返回任何类型的对象。
ItemStack item = ...;
// 编辑原始物品
RtagItem.edit(item, tag -> {
tag.set("Custom Text", "display", "name");
tag.set(30, "someKey");
});
// 返回一个副本
ItemStack copy = RtagItem.edit(item, tag -> {
tag.set(30, "someKey");
return tag.loadCopy();
});2️⃣ 编辑数据组件!(实验性)
自 Minecraft 1.20.5 起,物品使用组件来保存原版数据。通过 RtagItem,你可以像操作普通 Java 对象一样简单地编辑组件。
RtagItem tag = new RtagItem(item);
if (tag.hasComponent("minecraft:custom_model_data")) {
tag.removeComponent("minecraft:custom_model_data");
} else {
tag.setComponent("minecraft:custom_model_data", 40);
}
Object component = tag.getComponent("minecraft:custom_model_data");
Integer number = ComponentType.encodeJava("minecraft:custom_model_data", component).orElse(null);3️⃣ 存储自定义对象
默认情况下,Rtag 使用 Bukkit 内部的 Gson 库来(反)序列化自定义对象,但你需要使用显式转换来获取它们。
Rtag rtag = new Rtag();
MyObject myObject = new MyObject();
rtag.set(compound, myObject, "CustomTagPath");
MyObject sameObject = rtag.getOptional(compound, "CustomTagPath").as(MyObject.class);你可以在 Rtag 实例中注册(反)序列化器,以通过自动转换来设置和获取自定义对象。此转换会在保存的标签中添加一个额外的键,以便使用提供的 ID 进行识别。
示例:自定义序列化器
public class MyObjectSerializer implements RtagSerializer<MyObject>, RtagDeserializer<MyObject> {
public MyObjectSerializer(Rtag rtag) {
rtag.putSerializer(MyObject.class, this);
rtag.putDeserializer(this);
}
// MyObject -> Map
@Override
public String getInID() {
// 建议使用唯一的命名空间键
return "myplugin:MyObject";
}
// Map -> MyObject
@Override
public String getOutID() {
return "myplugin:MyObject";
}
@Override
public Map<String, Object> serialize(MyObject object) {
// 将你的自定义对象转换为 Map
}
@Override
public MyObject deserialize(Map<String, Object> compound) {
// 将 compound 转换回你的自定义对象
}
}注册后,你可以无需显式转换即可获取自定义对象。
Rtag rtag = new Rtag();
new MyObjectSerializer(rtag);
MyObject myObject = new MyObject();
rtag.set(compound, myObject, "CustomTagPath");
MyObject sameObject = rtag.get(compound, "CustomTagPath");4️⃣ TagStream 实例
通过 ItemTagStream 实例,你可以将物品转换为 Base64、文件、字节数组、Map、字符串,反之亦然。这包括跨版本支持!在任何版本上保存物品,并在任何版本上获取,没有兼容性问题。材料、附魔、药水等都将被转换!
ItemTagStream tag = ItemTagStream.INSTANCE;
String string = tag.toBase64(item);
ItemStack sameItem = tag.fromBase64(string)[0];5️⃣ 带纹理的头颅
使用 SkullTexture 类,你可以通过 base64、URL、纹理 ID、玩家名或 UUID 获取带纹理的头颅。
// Base64
ItemStack head = SkullTexture.getTexturedHead("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZmVkZmEyZTBmZGVhMGMwNDIzODA0Y2RiNWI2MmFkMDVhNmU5MTRjMDQ2YzRhM2I3ZTM1NWJmODEyNjkxMjVmZCJ9fQ==");
// URL
ItemStack head = SkullTexture.getTexturedHead("http://textures.minecraft.net/texture/fedfa2e0fdea0c0423804cdb5b62ad05a6e914c046c4a3b7e355bf81269125fd");
// 纹理 ID
ItemStack head = SkullTexture.getTexturedHead("fedfa2e0fdea0c0423804cdb5b62ad05a6e914c046c4a3b7e355bf81269125fd");
// 玩家名
ItemStack head = SkullTexture.getTexturedHead("Rubenicos");
// 玩家 UUID
ItemStack head = SkullTexture.getTexturedHead("7ca003dc-175f-4f1f-b490-5651045311ad");6️⃣ 聊天组件
使用 ChatComponent 类,你可以将(JSON)字符串转换为聊天组件,反之亦然。
// 转换为组件
Object component = ChatComponent.fromJson("{ \"bold\":true, \"italic\":false, \"color\":\"dark_purple\", \"text\":\"Colored text!\" }");
Object sameComponent = ChatComponent.fromString("§5§lColored text!");
// 从组件转换
String json = ChatComponent.toJson(component);
String string = ChatComponent.toString(component);
// 跨兼容性转换
String json = ChatComponent.toJson("§5§lColored text!");
String string = ChatComponent.toString("{ \"bold\":true, \"italic\":false, \"color\":\"dark_purple\", \"text\":\"Colored text!\" }");美观的 NBT 格式化
更多信息,请访问 [Wiki 页面](the wiki page)。
- 使用默认、十六进制或 MiniMessage 调色板将任何 NBT 对象格式化为单行或多行。
- 或使用你的自定义调色板。