▶️ ЗАБЕРИ СВОИ 8 ПОДАРКОВ 🎁 ПРИ СОЗДАНИИ СВОЕГО МАЙНКРАФТ СЕРВЕРА
Rtag

Rtag

Rtag - это Bukkit-библиотека для удобной работы с NBT-тегами и data components в Minecraft. Позволяет легко читать и изменять данные предметов, блоков и сущностей без NMS, поддерживает кросс-версионность и простое подключение.

Оцените первым
2.3K
9

Rtag - это библиотека (плагин) для серверов на Bukkit/Spigot/Paper, которая упрощает работу с NBT-данными. Если вы когда-нибудь пытались сохранить кастомные данные на предмете или сущности стандартными средствами Майнкрафт, то знаете, как это муторно. Rtag решает эту проблему: больше не нужно лезть в NMS и писать тонны кода для каждой версии Minecraft.

Для владельцев серверов

Установка

Скачайте .jar файл Rtag и поместите его в папку plugins вашего сервера. Перезагрузите сервер - библиотека готова к работе.

Требования

  • Minecraft 1.8.8 и выше (старые версии могут не поддерживаться)
  • Java 11 или новее (даже старые версии MC работают на Java 11)

Совместимость

✅ Bukkit, Spigot, Paper (включая Paper с Mojang Mappings), Folia и любые форки без craftbukkit relocation.

Для разработчиков

Что такое Rtag?

Rtag предоставляет простой API для редактирования NBT-тегов без использования NMS, что особенно важно для больших серверов - никакого удара по производительности. Библиотека полностью shadeable: вы можете включить её прямо в свой плагин.

Rtag конвертирует любой Java-объект в NBT-тег и обратно. Примеры:

// Работа с предметом
RtagItem tag = new RtagItem(item);
// Работа с сущностью
RtagEntity tag = new RtagEntity(entity);
// Работа с блоком
RtagBlock tag = new RtagBlock(block);

// --- Запись значений
// Установить значение "Custom Text" по пути "display.Name"
tag.set("Custom Text", "display", "Name");
// Установить целое число по пути "someKey"
tag.set(40, "someKey");
// Поддержка любых объектов, например MyObject
MyObject myobject = new MyObject();
tag.set(myobject, "any", "path");

// Работа со списками
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");
// Безопасное получение с дефолтным значением -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);
// Слияние значений
tag.merge(Map.of("asd", 123, "someKey", 41), true);

// Получение списков
List<Short> list = tag.get("list", "path");
// Элемент списка по индексу
short listValue = tag.get("list", "path", 0); // индекс 0

// Получение всего тега как Map Java-объектов
Map<String, Object> map = tag.get();

// --- Применение изменений к объекту
tag.load();
// RtagItem может создать копию предмета с изменениями
ItemStack itemCopy = tag.loadCopy();

// --- Обновление тега, если исходный объект был изменён извне
tag.update();

Подключение Rtag

Для Gradle Groovy:

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:

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:

<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>

Возможности Rtag

Почему именно Rtag, а не другие библиотеки?

1. Простота

Не нужно быть экспертом в NBT - простые методы set/get работают с обычными Java-объектами.

Rtag rtag = new Rtag();
rtag.set(compound, "Normal string", "CustomTagPath");
String string = rtag.get(compound, "CustomTagPath");

Встроенные редакторы (RtagItem, RtagEntity, RtagBlock) предлагают удобные методы:

RtagItem tag = new RtagItem(item);
tag.setUnbreakable(true);
tag.setRepairCost(20);
int level = tag.getEnchantmentLevel("unbreaking"); // принимает enum, имя или ID

RtagEntity tag = new RtagEntity(entity);
tag.setAttributeBase("generic.attackDamage", 0.5);

RtagBlock tag = new RtagBlock(block);
tag.setCustomName("§eЦветное имя");

Можно редактировать объекты с помощью лямбд:

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. Редактирование data components (экспериментально)

Начиная с Minecraft 1.20.5 предметы используют компоненты для хранения ванильных данных. RtagItem позволяет работать с ними так же просто, как с обычными тегами.

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 использует встроенную Gson для сериализации, но вы можете зарегистрировать свои (де)сериализаторы для автоматического преобразования.

Rtag rtag = new Rtag();
MyObject myObject = new MyObject();

rtag.set(compound, myObject, "CustomTagPath");
MyObject sameObject = rtag.getOptional(compound, "CustomTagPath").as(MyObject.class);

Пример регистрации сериализатора:

public class MyObjectSerializer implements RtagSerializer<MyObject>, RtagDeserializer<MyObject> {
 
    public MyObjectSerializer(Rtag rtag) {
        rtag.putSerializer(MyObject.class, this);
        rtag.putDeserializer(this);
    }
 
    @Override
    public String getInID() {
        return "myplugin: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) {
        // Преобразуйте Map в объект
    }
}

После регистрации можно получать объекты без явного приведения:

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!\"}");

Pretty NBT

Форматирование NBT в одну или несколько строк с использованием стандартной, hex или minimessage цветовой палитры (подробнее в вики).

Часто задаваемые вопросы

Совместимость

Minecraft: Java Edition

26.2.x26.1.x1.21.x1.20.x1.19.x1.18.x1.17.x1.16.x1.15.x1.14.x1.13.x1.12.x1.11.x1.10.x1.9.x1.8.x

Поддерживаемые окружения

Сервер

Ссылки

Создатели

Детали

Лицензия:
Опубликован:3 года назад
Обновлён:1 месяц назад
Главная