From e69f91914e766e483277e5922b7494ecd6057c60 Mon Sep 17 00:00:00 2001 From: 3944Realms Date: Wed, 15 Oct 2025 17:21:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86NBTBuilder=E5=8F=98=E6=9B=B4=E4=B8=BAN?= =?UTF-8?q?BTWriter=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib39/util/nbt/NBTBuilder.java | 545 ----------------- .../r3944realms/lib39/util/nbt/NBTReader.java | 286 ++++++++- .../r3944realms/lib39/util/nbt/NBTWriter.java | 567 +++++++++++++++++- 3 files changed, 831 insertions(+), 567 deletions(-) delete mode 100644 src/main/java/top/r3944realms/lib39/util/nbt/NBTBuilder.java diff --git a/src/main/java/top/r3944realms/lib39/util/nbt/NBTBuilder.java b/src/main/java/top/r3944realms/lib39/util/nbt/NBTBuilder.java deleted file mode 100644 index c74a311..0000000 --- a/src/main/java/top/r3944realms/lib39/util/nbt/NBTBuilder.java +++ /dev/null @@ -1,545 +0,0 @@ -package top.r3944realms.lib39.util.nbt; - -import net.minecraft.nbt.*; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.UUID; -import java.util.function.Consumer; - -@SuppressWarnings("unused") -public class NBTBuilder { - private final CompoundTag root; - - private NBTBuilder() { - this.root = new CompoundTag(); - } - - private NBTBuilder(CompoundTag existingTag) { - this.root = existingTag; - } - - /** - * 创建一个新的NBT构建器 - */ - @Contract(value = " -> new", pure = true) - public static @NotNull NBTBuilder builder() { - return new NBTBuilder(); - } - - /** - * 基于现有CompoundTag创建构建器 - */ - @Contract(value = "_ -> new", pure = true) - public static @NotNull NBTBuilder of(CompoundTag existingTag) { - return new NBTBuilder(existingTag); - } - - public NBTBuilder byteValue(String key, byte value) { - root.putByte(key, value); - return this; - } - - public NBTBuilder shortValue(String key, short value) { - root.putShort(key, value); - return this; - } - - public NBTBuilder intValue(String key, int value) { - root.putInt(key, value); - return this; - } - - public NBTBuilder longValue(String key, long value) { - root.putLong(key, value); - return this; - } - - public NBTBuilder floatValue(String key, float value) { - root.putFloat(key, value); - return this; - } - - public NBTBuilder doubleValue(String key, double value) { - root.putDouble(key, value); - return this; - } - - public NBTBuilder booleanValue(String key, boolean value) { - root.putBoolean(key, value); - return this; - } - public NBTBuilder string(String key, String value) { - if (value != null) { - root.putString(key, value); - } - return this; - } - // 包装类型 - null安全的版本 - public NBTBuilder string(String key, String value, String defaultValue) { - if (value != null) { - root.putString(key, value); - } else if (defaultValue != null) { - root.putString(key, defaultValue); - } - return this; - } - - - public NBTBuilder byteValue(String key, Byte value) { - if (value != null) { - root.putByte(key, value); - } - return this; - } - - public NBTBuilder byteValue(String key, Byte value, byte defaultValue) { - root.putByte(key, value != null ? value : defaultValue); - return this; - } - - public NBTBuilder shortValue(String key, Short value) { - if (value != null) { - root.putShort(key, value); - } - return this; - } - - public NBTBuilder shortValue(String key, Short value, short defaultValue) { - root.putShort(key, value != null ? value : defaultValue); - return this; - } - - public NBTBuilder intValue(String key, Integer value) { - if (value != null) { - root.putInt(key, value); - } - return this; - } - - public NBTBuilder intValue(String key, Integer value, int defaultValue) { - root.putInt(key, value != null ? value : defaultValue); - return this; - } - - public NBTBuilder longValue(String key, Long value) { - if (value != null) { - root.putLong(key, value); - } - return this; - } - - public NBTBuilder longValue(String key, Long value, long defaultValue) { - root.putLong(key, value != null ? value : defaultValue); - return this; - } - - public NBTBuilder floatValue(String key, Float value) { - if (value != null) { - root.putFloat(key, value); - } - return this; - } - - public NBTBuilder floatValue(String key, Float value, float defaultValue) { - root.putFloat(key, value != null ? value : defaultValue); - return this; - } - - public NBTBuilder doubleValue(String key, Double value) { - if (value != null) { - root.putDouble(key, value); - } - return this; - } - - public NBTBuilder doubleValue(String key, Double value, double defaultValue) { - root.putDouble(key, value != null ? value : defaultValue); - return this; - } - - public NBTBuilder booleanValue(String key, Boolean value) { - if (value != null) { - root.putBoolean(key, value); - } - return this; - } - - public NBTBuilder booleanValue(String key, Boolean value, boolean defaultValue) { - root.putBoolean(key, value != null ? value : defaultValue); - return this; - } - - // 数组类型 - 原始数组 - public NBTBuilder byteArray(String key, byte[] value) { - if (value != null) { - root.putByteArray(key, value); - } - return this; - } - - public NBTBuilder intArray(String key, int[] value) { - if (value != null) { - root.putIntArray(key, value); - } - return this; - } - - public NBTBuilder longArray(String key, long[] value) { - if (value != null) { - root.putLongArray(key, value); - } - return this; - } - - // UUID支持 - public NBTBuilder uuid(String key, UUID value) { - if (value != null) { - root.putUUID(key, value); - } - return this; - } - - public NBTBuilder uuid(String key, UUID value, UUID defaultValue) { - if (value != null) { - root.putUUID(key, value); - } else if (defaultValue != null) { - root.putUUID(key, defaultValue); - } - return this; - } - - // 嵌套CompoundTag - public NBTBuilder compound(String key, Consumer consumer) { - if (consumer != null) { - NBTBuilder nestedBuilder = new NBTBuilder(); - consumer.accept(nestedBuilder); - CompoundTag nestedTag = nestedBuilder.build(); - if (!nestedTag.isEmpty()) { - root.put(key, nestedTag); - } - } - return this; - } - - public NBTBuilder compound(String key, CompoundTag compoundTag) { - if (compoundTag != null && !compoundTag.isEmpty()) { - root.put(key, compoundTag); - } - return this; - } - - public NBTBuilder compoundIf(String key, boolean condition, Consumer consumer) { - if (condition && consumer != null) { - return compound(key, consumer); - } - return this; - } - - // ListTag支持 - public NBTBuilder list(String key, Consumer consumer) { - if (consumer != null) { - ListNBTBuilder listBuilder = new ListNBTBuilder(); - consumer.accept(listBuilder); - ListTag listTag = listBuilder.build(); - if (!listTag.isEmpty()) { - root.put(key, listTag); - } - } - return this; - } - - public NBTBuilder list(String key, ListTag listTag) { - if (listTag != null && !listTag.isEmpty()) { - root.put(key, listTag); - } - return this; - } - - public NBTBuilder listIf(String key, boolean condition, Consumer consumer) { - if (condition && consumer != null) { - return list(key, consumer); - } - return this; - } - - // 直接操作Tag - public NBTBuilder tag(String key, Tag tag) { - if (tag != null) { - root.put(key, tag); - } - return this; - } - - // 条件添加方法 - public NBTBuilder stringIf(String key, String value, boolean condition) { - if (condition && value != null) { - root.putString(key, value); - } - return this; - } - - public NBTBuilder intValueIf(String key, Integer value, boolean condition) { - if (condition && value != null) { - root.putInt(key, value); - } - return this; - } - - public NBTBuilder longValueIf(String key, Long value, boolean condition) { - if (condition && value != null) { - root.putLong(key, value); - } - return this; - } - - public NBTBuilder booleanValueIf(String key, Boolean value, boolean condition) { - if (condition && value != null) { - root.putBoolean(key, value); - } - return this; - } - - // 移除标签 - public NBTBuilder remove(String key) { - root.remove(key); - return this; - } - - // 构建最终的CompoundTag - public CompoundTag build() { - return root; - } - - - /** - * ListTag专用的构建器 - 同样支持null安全 - */ - public static class ListNBTBuilder { - private final ListTag list; - - private ListNBTBuilder() { - this.list = new ListTag(); - } - - // 原始类型方法 - public ListNBTBuilder addString(String value) { - list.add(StringTag.valueOf(value)); - return this; - } - - public ListNBTBuilder addByte(byte value) { - list.add(ByteTag.valueOf(value)); - return this; - } - - public ListNBTBuilder addShort(short value) { - list.add(ShortTag.valueOf(value)); - return this; - } - - public ListNBTBuilder addInt(int value) { - list.add(IntTag.valueOf(value)); - return this; - } - - public ListNBTBuilder addLong(long value) { - list.add(LongTag.valueOf(value)); - return this; - } - - public ListNBTBuilder addFloat(float value) { - list.add(FloatTag.valueOf(value)); - return this; - } - - public ListNBTBuilder addDouble(double value) { - list.add(DoubleTag.valueOf(value)); - return this; - } - - public ListNBTBuilder addBoolean(boolean value) { - list.add(ByteTag.valueOf(value)); - return this; - } - - public ListNBTBuilder addByteArray(byte[] value) { - if (value != null) { - list.add(new ByteArrayTag(value)); - } - return this; - } - - public ListNBTBuilder addIntArray(int[] value) { - if (value != null) { - list.add(new IntArrayTag(value)); - } - return this; - } - - public ListNBTBuilder addLongArray(long[] value) { - if (value != null) { - list.add(new LongArrayTag(value)); - } - return this; - } - - // 包装类型方法 - null安全 - public ListNBTBuilder addString(String value, String defaultValue) { - list.add(StringTag.valueOf(value != null ? value : defaultValue)); - return this; - } - - public ListNBTBuilder addStringIf(String value) { - if (value != null) { - list.add(StringTag.valueOf(value)); - } - return this; - } - - public ListNBTBuilder addByte(Byte value) { - if (value != null) { - list.add(ByteTag.valueOf(value)); - } - return this; - } - - public ListNBTBuilder addByte(Byte value, byte defaultValue) { - list.add(ByteTag.valueOf(value != null ? value : defaultValue)); - return this; - } - - public ListNBTBuilder addShort(Short value) { - if (value != null) { - list.add(ShortTag.valueOf(value)); - } - return this; - } - - public ListNBTBuilder addShort(Short value, short defaultValue) { - list.add(ShortTag.valueOf(value != null ? value : defaultValue)); - return this; - } - - public ListNBTBuilder addInt(Integer value) { - if (value != null) { - list.add(IntTag.valueOf(value)); - } - return this; - } - - public ListNBTBuilder addInt(Integer value, int defaultValue) { - list.add(IntTag.valueOf(value != null ? value : defaultValue)); - return this; - } - - public ListNBTBuilder addLong(Long value) { - if (value != null) { - list.add(LongTag.valueOf(value)); - } - return this; - } - - public ListNBTBuilder addLong(Long value, long defaultValue) { - list.add(LongTag.valueOf(value != null ? value : defaultValue)); - return this; - } - - public ListNBTBuilder addFloat(Float value) { - if (value != null) { - list.add(FloatTag.valueOf(value)); - } - return this; - } - - public ListNBTBuilder addFloat(Float value, float defaultValue) { - list.add(FloatTag.valueOf(value != null ? value : defaultValue)); - return this; - } - - public ListNBTBuilder addDouble(Double value) { - if (value != null) { - list.add(DoubleTag.valueOf(value)); - } - return this; - } - - public ListNBTBuilder addDouble(Double value, double defaultValue) { - list.add(DoubleTag.valueOf(value != null ? value : defaultValue)); - return this; - } - - public ListNBTBuilder addBoolean(Boolean value) { - if (value != null) { - list.add(ByteTag.valueOf(value)); - } - return this; - } - - public ListNBTBuilder addBoolean(Boolean value, boolean defaultValue) { - list.add(ByteTag.valueOf(value != null ? value : defaultValue)); - return this; - } - - public ListNBTBuilder addCompound(Consumer consumer) { - if (consumer != null) { - NBTBuilder compoundBuilder = new NBTBuilder(); - consumer.accept(compoundBuilder); - CompoundTag compoundTag = compoundBuilder.build(); - if (!compoundTag.isEmpty()) { - list.add(compoundTag); - } - } - return this; - } - - public ListNBTBuilder addTag(Tag tag) { - if (tag != null) { - list.add(tag); - } - return this; - } - - public ListNBTBuilder addIf(boolean condition, Consumer consumer) { - if (condition && consumer != null) { - consumer.accept(this); - } - return this; - } - - public ListTag build() { - return list; - } - } - - // 便捷静态方法 - public static CompoundTag create(Consumer consumer) { - NBTBuilder builder = new NBTBuilder(); - if (consumer != null) { - consumer.accept(builder); - } - return builder.build(); - } - - public static ListTag createList(Consumer consumer) { - ListNBTBuilder builder = new ListNBTBuilder(); - if (consumer != null) { - consumer.accept(builder); - } - return builder.build(); - } - - /** - * 检查构建的NBT是否为空 - */ - public boolean isEmpty() { - return root.isEmpty(); - } - - /** - * 获取NBT中所有键的集合 - */ - public java.util.Set getAllKeys() { - return root.getAllKeys(); - } -} \ No newline at end of file diff --git a/src/main/java/top/r3944realms/lib39/util/nbt/NBTReader.java b/src/main/java/top/r3944realms/lib39/util/nbt/NBTReader.java index f3a5ec0..b953354 100644 --- a/src/main/java/top/r3944realms/lib39/util/nbt/NBTReader.java +++ b/src/main/java/top/r3944realms/lib39/util/nbt/NBTReader.java @@ -16,15 +16,281 @@ package top.r3944realms.lib39.util.nbt; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; import net.minecraft.world.phys.Vec3; -import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; +import java.util.function.Consumer; @SuppressWarnings("unused") public class NBTReader { - private NBTReader() {} - @Contract("_ -> new") - public static @NotNull Vec3 readVec3(@NotNull CompoundTag nbt) { + private final CompoundTag nbt; + + private NBTReader(CompoundTag nbt) { + this.nbt = nbt; + } + + /** + * 从CompoundTag创建读取器 + */ + @NotNull + public static NBTReader of(@NotNull CompoundTag nbt) { + return new NBTReader(nbt); + } + + // 基本读取方法 - 直接赋值给成员变量 + public NBTReader string(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getString(key)); + } + return this; + } + + public NBTReader string(String key, Consumer setter, String defaultValue) { + setter.accept(nbt.contains(key) ? nbt.getString(key) : defaultValue); + return this; + } + + public NBTReader byteValue(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getByte(key)); + } + return this; + } + + public NBTReader byteValue(String key, Consumer setter, byte defaultValue) { + setter.accept(nbt.contains(key) ? nbt.getByte(key) : defaultValue); + return this; + } + + public NBTReader shortValue(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getShort(key)); + } + return this; + } + + public NBTReader shortValue(String key, Consumer setter, short defaultValue) { + setter.accept(nbt.contains(key) ? nbt.getShort(key) : defaultValue); + return this; + } + + public NBTReader intValue(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getInt(key)); + } + return this; + } + + public NBTReader intValue(String key, Consumer setter, int defaultValue) { + setter.accept(nbt.contains(key) ? nbt.getInt(key) : defaultValue); + return this; + } + + public NBTReader longValue(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getLong(key)); + } + return this; + } + + public NBTReader longValue(String key, Consumer setter, long defaultValue) { + setter.accept(nbt.contains(key) ? nbt.getLong(key) : defaultValue); + return this; + } + + public NBTReader floatValue(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getFloat(key)); + } + return this; + } + + public NBTReader floatValue(String key, Consumer setter, float defaultValue) { + setter.accept(nbt.contains(key) ? nbt.getFloat(key) : defaultValue); + return this; + } + + public NBTReader doubleValue(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getDouble(key)); + } + return this; + } + + public NBTReader doubleValue(String key, Consumer setter, double defaultValue) { + setter.accept(nbt.contains(key) ? nbt.getDouble(key) : defaultValue); + return this; + } + + public NBTReader booleanValue(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getBoolean(key)); + } + return this; + } + + public NBTReader booleanValue(String key, Consumer setter, boolean defaultValue) { + setter.accept(nbt.contains(key) ? nbt.getBoolean(key) : defaultValue); + return this; + } + + // 数组类型 + public NBTReader byteArray(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getByteArray(key)); + } + return this; + } + + public NBTReader intArray(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getIntArray(key)); + } + return this; + } + + public NBTReader longArray(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getLongArray(key)); + } + return this; + } + + // UUID + public NBTReader uuid(String key, Consumer setter) { + if (nbt.hasUUID(key)) { + setter.accept(nbt.getUUID(key)); + } + return this; + } + + public NBTReader uuid(String key, Consumer setter, UUID defaultValue) { + setter.accept(nbt.hasUUID(key) ? nbt.getUUID(key) : defaultValue); + return this; + } + + // CompoundTag + public NBTReader compound(String key, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getCompound(key)); + } + return this; + } + + public NBTReader compound(String key, Consumer setter, CompoundTag defaultValue) { + setter.accept(nbt.contains(key) ? nbt.getCompound(key) : defaultValue); + return this; + } + + // ListTag + public NBTReader list(String key, int type, Consumer setter) { + if (nbt.contains(key)) { + setter.accept(nbt.getList(key, type)); + } + return this; + } + + // Vec3支持 + public NBTReader vec3(String key, Consumer setter) { + if (nbt.contains(key)) { + CompoundTag vecTag = nbt.getCompound(key); + if (vecTag.contains("X") && vecTag.contains("Y") && vecTag.contains("Z")) { + setter.accept(new Vec3( + vecTag.getDouble("X"), + vecTag.getDouble("Y"), + vecTag.getDouble("Z") + )); + } + } + return this; + } + + public NBTReader vec3(String key, Consumer setter, Vec3 defaultValue) { + if (nbt.contains(key)) { + CompoundTag vecTag = nbt.getCompound(key); + if (vecTag.contains("X") && vecTag.contains("Y") && vecTag.contains("Z")) { + setter.accept(new Vec3( + vecTag.getDouble("X"), + vecTag.getDouble("Y"), + vecTag.getDouble("Z") + )); + return this; + } + } + setter.accept(defaultValue); + return this; + } + + // 枚举支持 + public > NBTReader enumValue(String key, Class enumClass, Consumer setter) { + if (nbt.contains(key)) { + String value = nbt.getString(key); + try { + setter.accept(Enum.valueOf(enumClass, value.toUpperCase())); + } catch (IllegalArgumentException ignored) { + // 保持setter的当前值 + } + } + return this; + } + + public > NBTReader enumValue(String key, Class enumClass, Consumer setter, T defaultValue) { + if (nbt.contains(key)) { + String value = nbt.getString(key); + try { + setter.accept(Enum.valueOf(enumClass, value.toUpperCase())); + return this; + } catch (IllegalArgumentException ignored) { + } + } + setter.accept(defaultValue); + return this; + } + + // 嵌套读取支持 + public NBTReader nested(String key, Consumer consumer) { + if (nbt.contains(key)) { + consumer.accept(new NBTReader(nbt.getCompound(key))); + } + return this; + } + + public NBTReader nested(String key, Consumer consumer, Runnable orElse) { + if (nbt.contains(key)) { + consumer.accept(new NBTReader(nbt.getCompound(key))); + } else { + orElse.run(); + } + return this; + } + + // 条件读取 + public NBTReader ifPresent(String key, Runnable action) { + if (nbt.contains(key)) { + action.run(); + } + return this; + } + + public NBTReader ifAbsent(String key, Runnable action) { + if (!nbt.contains(key)) { + action.run(); + } + return this; + } + + // 获取原始NBT + @NotNull + public CompoundTag getRaw() { + return nbt; + } + + // 便捷的静态方法(保持原有功能) + @NotNull + public static Vec3 readVec3(@NotNull CompoundTag nbt) { if (nbt.contains("X") && nbt.contains("Y") && nbt.contains("Z")) { return new Vec3( nbt.getDouble("X"), @@ -35,4 +301,16 @@ public class NBTReader { throw new IllegalArgumentException("NBT is missing X, Y, or Z value for Vec3"); } } + + @Nullable + public static Vec3 readVec3Safe(@NotNull CompoundTag nbt) { + if (nbt.contains("X") && nbt.contains("Y") && nbt.contains("Z")) { + return new Vec3( + nbt.getDouble("X"), + nbt.getDouble("Y"), + nbt.getDouble("Z") + ); + } + return null; + } } diff --git a/src/main/java/top/r3944realms/lib39/util/nbt/NBTWriter.java b/src/main/java/top/r3944realms/lib39/util/nbt/NBTWriter.java index ba9752c..80dcce3 100644 --- a/src/main/java/top/r3944realms/lib39/util/nbt/NBTWriter.java +++ b/src/main/java/top/r3944realms/lib39/util/nbt/NBTWriter.java @@ -1,28 +1,549 @@ -/* - * Super Lead rope mod - * Copyright (C) 2025 R3944Realms - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - package top.r3944realms.lib39.util.nbt; -import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.*; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; +import java.util.function.Consumer; @SuppressWarnings("unused") public class NBTWriter { - private NBTWriter() {} + private final CompoundTag root; + + private NBTWriter() { + this.root = new CompoundTag(); + } + + private NBTWriter(CompoundTag existingTag) { + this.root = existingTag; + } + + /** + * 创建一个新的NBT构建器 + */ + @Contract(value = " -> new", pure = true) + public static @NotNull NBTWriter builder() { + return new NBTWriter(); + } + + /** + * 基于现有CompoundTag创建构建器 + */ + @Contract(value = "_ -> new", pure = true) + public static @NotNull NBTWriter of(CompoundTag existingTag) { + return new NBTWriter(existingTag); + } + + public NBTWriter byteValue(String key, byte value) { + root.putByte(key, value); + return this; + } + + public NBTWriter shortValue(String key, short value) { + root.putShort(key, value); + return this; + } + + public NBTWriter intValue(String key, int value) { + root.putInt(key, value); + return this; + } + + public NBTWriter longValue(String key, long value) { + root.putLong(key, value); + return this; + } + + public NBTWriter floatValue(String key, float value) { + root.putFloat(key, value); + return this; + } + + public NBTWriter doubleValue(String key, double value) { + root.putDouble(key, value); + return this; + } + + public NBTWriter booleanValue(String key, boolean value) { + root.putBoolean(key, value); + return this; + } + public NBTWriter string(String key, String value) { + if (value != null) { + root.putString(key, value); + } + return this; + } + // 包装类型 - null安全的版本 + public NBTWriter string(String key, String value, String defaultValue) { + if (value != null) { + root.putString(key, value); + } else if (defaultValue != null) { + root.putString(key, defaultValue); + } + return this; + } + + + public NBTWriter byteValue(String key, Byte value) { + if (value != null) { + root.putByte(key, value); + } + return this; + } + + public NBTWriter byteValue(String key, Byte value, byte defaultValue) { + root.putByte(key, value != null ? value : defaultValue); + return this; + } + + public NBTWriter shortValue(String key, Short value) { + if (value != null) { + root.putShort(key, value); + } + return this; + } + + public NBTWriter shortValue(String key, Short value, short defaultValue) { + root.putShort(key, value != null ? value : defaultValue); + return this; + } + + public NBTWriter intValue(String key, Integer value) { + if (value != null) { + root.putInt(key, value); + } + return this; + } + + public NBTWriter intValue(String key, Integer value, int defaultValue) { + root.putInt(key, value != null ? value : defaultValue); + return this; + } + + public NBTWriter longValue(String key, Long value) { + if (value != null) { + root.putLong(key, value); + } + return this; + } + + public NBTWriter longValue(String key, Long value, long defaultValue) { + root.putLong(key, value != null ? value : defaultValue); + return this; + } + + public NBTWriter floatValue(String key, Float value) { + if (value != null) { + root.putFloat(key, value); + } + return this; + } + + public NBTWriter floatValue(String key, Float value, float defaultValue) { + root.putFloat(key, value != null ? value : defaultValue); + return this; + } + + public NBTWriter doubleValue(String key, Double value) { + if (value != null) { + root.putDouble(key, value); + } + return this; + } + + public NBTWriter doubleValue(String key, Double value, double defaultValue) { + root.putDouble(key, value != null ? value : defaultValue); + return this; + } + + public NBTWriter booleanValue(String key, Boolean value) { + if (value != null) { + root.putBoolean(key, value); + } + return this; + } + + public NBTWriter booleanValue(String key, Boolean value, boolean defaultValue) { + root.putBoolean(key, value != null ? value : defaultValue); + return this; + } + + // 数组类型 - 原始数组 + public NBTWriter byteArray(String key, byte[] value) { + if (value != null) { + root.putByteArray(key, value); + } + return this; + } + + public NBTWriter intArray(String key, int[] value) { + if (value != null) { + root.putIntArray(key, value); + } + return this; + } + + public NBTWriter longArray(String key, long[] value) { + if (value != null) { + root.putLongArray(key, value); + } + return this; + } + + // UUID支持 + public NBTWriter uuid(String key, UUID value) { + if (value != null) { + root.putUUID(key, value); + } + return this; + } + + public NBTWriter uuid(String key, UUID value, UUID defaultValue) { + if (value != null) { + root.putUUID(key, value); + } else if (defaultValue != null) { + root.putUUID(key, defaultValue); + } + return this; + } + + // 嵌套CompoundTag + public NBTWriter compound(String key, Consumer consumer) { + if (consumer != null) { + NBTWriter nestedBuilder = new NBTWriter(); + consumer.accept(nestedBuilder); + CompoundTag nestedTag = nestedBuilder.build(); + if (!nestedTag.isEmpty()) { + root.put(key, nestedTag); + } + } + return this; + } + + public NBTWriter compound(String key, CompoundTag compoundTag) { + if (compoundTag != null && !compoundTag.isEmpty()) { + root.put(key, compoundTag); + } + return this; + } + + public NBTWriter compoundIf(String key, boolean condition, Consumer consumer) { + if (condition && consumer != null) { + return compound(key, consumer); + } + return this; + } + + // ListTag支持 + public NBTWriter list(String key, Consumer consumer) { + if (consumer != null) { + ListNBTBuilder listBuilder = new ListNBTBuilder(); + consumer.accept(listBuilder); + ListTag listTag = listBuilder.build(); + if (!listTag.isEmpty()) { + root.put(key, listTag); + } + } + return this; + } + + public NBTWriter list(String key, ListTag listTag) { + if (listTag != null && !listTag.isEmpty()) { + root.put(key, listTag); + } + return this; + } + + public NBTWriter listIf(String key, boolean condition, Consumer consumer) { + if (condition && consumer != null) { + return list(key, consumer); + } + return this; + } + + // 直接操作Tag + public NBTWriter tag(String key, Tag tag) { + if (tag != null) { + root.put(key, tag); + } + return this; + } + + // 条件添加方法 + public NBTWriter stringIf(String key, String value, boolean condition) { + if (condition && value != null) { + root.putString(key, value); + } + return this; + } + + public NBTWriter intValueIf(String key, Integer value, boolean condition) { + if (condition && value != null) { + root.putInt(key, value); + } + return this; + } + + public NBTWriter longValueIf(String key, Long value, boolean condition) { + if (condition && value != null) { + root.putLong(key, value); + } + return this; + } + + public NBTWriter booleanValueIf(String key, Boolean value, boolean condition) { + if (condition && value != null) { + root.putBoolean(key, value); + } + return this; + } + + // 移除标签 + public NBTWriter remove(String key) { + root.remove(key); + return this; + } + + // 构建最终的CompoundTag + public CompoundTag build() { + return root; + } + + + /** + * ListTag专用的构建器 - 同样支持null安全 + */ + public static class ListNBTBuilder { + private final ListTag list; + + private ListNBTBuilder() { + this.list = new ListTag(); + } + + // 原始类型方法 + public ListNBTBuilder addString(String value) { + list.add(StringTag.valueOf(value)); + return this; + } + + public ListNBTBuilder addByte(byte value) { + list.add(ByteTag.valueOf(value)); + return this; + } + + public ListNBTBuilder addShort(short value) { + list.add(ShortTag.valueOf(value)); + return this; + } + + public ListNBTBuilder addInt(int value) { + list.add(IntTag.valueOf(value)); + return this; + } + + public ListNBTBuilder addLong(long value) { + list.add(LongTag.valueOf(value)); + return this; + } + + public ListNBTBuilder addFloat(float value) { + list.add(FloatTag.valueOf(value)); + return this; + } + + public ListNBTBuilder addDouble(double value) { + list.add(DoubleTag.valueOf(value)); + return this; + } + + public ListNBTBuilder addBoolean(boolean value) { + list.add(ByteTag.valueOf(value)); + return this; + } + + public ListNBTBuilder addByteArray(byte[] value) { + if (value != null) { + list.add(new ByteArrayTag(value)); + } + return this; + } + + public ListNBTBuilder addIntArray(int[] value) { + if (value != null) { + list.add(new IntArrayTag(value)); + } + return this; + } + + public ListNBTBuilder addLongArray(long[] value) { + if (value != null) { + list.add(new LongArrayTag(value)); + } + return this; + } + + // 包装类型方法 - null安全 + public ListNBTBuilder addString(String value, String defaultValue) { + list.add(StringTag.valueOf(value != null ? value : defaultValue)); + return this; + } + + public ListNBTBuilder addStringIf(String value) { + if (value != null) { + list.add(StringTag.valueOf(value)); + } + return this; + } + + public ListNBTBuilder addByte(Byte value) { + if (value != null) { + list.add(ByteTag.valueOf(value)); + } + return this; + } + + public ListNBTBuilder addByte(Byte value, byte defaultValue) { + list.add(ByteTag.valueOf(value != null ? value : defaultValue)); + return this; + } + + public ListNBTBuilder addShort(Short value) { + if (value != null) { + list.add(ShortTag.valueOf(value)); + } + return this; + } + + public ListNBTBuilder addShort(Short value, short defaultValue) { + list.add(ShortTag.valueOf(value != null ? value : defaultValue)); + return this; + } + + public ListNBTBuilder addInt(Integer value) { + if (value != null) { + list.add(IntTag.valueOf(value)); + } + return this; + } + + public ListNBTBuilder addInt(Integer value, int defaultValue) { + list.add(IntTag.valueOf(value != null ? value : defaultValue)); + return this; + } + + public ListNBTBuilder addLong(Long value) { + if (value != null) { + list.add(LongTag.valueOf(value)); + } + return this; + } + + public ListNBTBuilder addLong(Long value, long defaultValue) { + list.add(LongTag.valueOf(value != null ? value : defaultValue)); + return this; + } + + public ListNBTBuilder addFloat(Float value) { + if (value != null) { + list.add(FloatTag.valueOf(value)); + } + return this; + } + + public ListNBTBuilder addFloat(Float value, float defaultValue) { + list.add(FloatTag.valueOf(value != null ? value : defaultValue)); + return this; + } + + public ListNBTBuilder addDouble(Double value) { + if (value != null) { + list.add(DoubleTag.valueOf(value)); + } + return this; + } + + public ListNBTBuilder addDouble(Double value, double defaultValue) { + list.add(DoubleTag.valueOf(value != null ? value : defaultValue)); + return this; + } + + public ListNBTBuilder addBoolean(Boolean value) { + if (value != null) { + list.add(ByteTag.valueOf(value)); + } + return this; + } + + public ListNBTBuilder addBoolean(Boolean value, boolean defaultValue) { + list.add(ByteTag.valueOf(value != null ? value : defaultValue)); + return this; + } + + public ListNBTBuilder addCompound(Consumer consumer) { + if (consumer != null) { + NBTWriter compoundBuilder = new NBTWriter(); + consumer.accept(compoundBuilder); + CompoundTag compoundTag = compoundBuilder.build(); + if (!compoundTag.isEmpty()) { + list.add(compoundTag); + } + } + return this; + } + + public ListNBTBuilder addTag(Tag tag) { + if (tag != null) { + list.add(tag); + } + return this; + } + + public ListNBTBuilder addIf(boolean condition, Consumer consumer) { + if (condition && consumer != null) { + consumer.accept(this); + } + return this; + } + + public ListTag build() { + return list; + } + } + + // 便捷静态方法 + public static CompoundTag create(Consumer consumer) { + NBTWriter builder = new NBTWriter(); + if (consumer != null) { + consumer.accept(builder); + } + return builder.build(); + } + + public static ListTag createList(Consumer consumer) { + ListNBTBuilder builder = new ListNBTBuilder(); + if (consumer != null) { + consumer.accept(builder); + } + return builder.build(); + } + + /** + * 检查构建的NBT是否为空 + */ + public boolean isEmpty() { + return root.isEmpty(); + } + + /** + * 获取NBT中所有键的集合 + */ + public java.util.Set getAllKeys() { + return root.getAllKeys(); + } @Contract("null -> fail") public static @NotNull CompoundTag writeVec3(Vec3 vec) { CompoundTag nbt = new CompoundTag(); @@ -33,4 +554,14 @@ public class NBTWriter { nbt.putDouble("Z", vec.z); return nbt; } -} + + public static @Nullable CompoundTag writeVec3Safe(Vec3 vec) { + CompoundTag nbt = new CompoundTag(); + if (vec == null) return null; + + nbt.putDouble("X", vec.x); + nbt.putDouble("Y", vec.y); + nbt.putDouble("Z", vec.z); + return nbt; + } +} \ No newline at end of file