mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-13 11:41:52 +01:00
Port to Hephaistos v2 (#424)
This commit is contained in:
parent
f43ffd64cb
commit
9ab4277502
10
build.gradle
10
build.gradle
@ -152,13 +152,13 @@ dependencies {
|
||||
api "org.jetbrains.kotlin:kotlin-reflect:${project.kotlinVersion}"
|
||||
|
||||
// NBT parsing/manipulation/saving
|
||||
api("com.github.jglrxavpok:Hephaistos:${project.hephaistosVersion}")
|
||||
api("com.github.jglrxavpok:Hephaistos:${project.hephaistosVersion}:gson")
|
||||
api("com.github.jglrxavpok:Hephaistos:${project.hephaistosVersion}") {
|
||||
api("io.github.jglrxavpok.hephaistos:common:${project.hephaistosVersion}")
|
||||
api("io.github.jglrxavpok.hephaistos:gson:${project.hephaistosVersion}")
|
||||
/* api("io.github.jglrxavpok.hephaistos:common:${project.hephaistosVersion}") {
|
||||
capabilities {
|
||||
requireCapability("org.jglrxavpok.nbt:Hephaistos-gson")
|
||||
requireCapability("io.github.jglrxavpok.hephaistos:Hephaistos-gson")
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
api "com.github.Minestom:DependencyGetter:v1.0.1"
|
||||
implementation 'com.github.Minestom:MinestomDataGenerator:801b8007cf'
|
||||
|
@ -3,6 +3,6 @@ mcVersion = 1.17
|
||||
|
||||
asmVersion=9.2
|
||||
mixinVersion=0.8.4
|
||||
hephaistosVersion=v1.1.8
|
||||
hephaistosVersion=2.3.0
|
||||
kotlinVersion=1.5.31
|
||||
adventureVersion=4.9.3
|
||||
adventureVersion=4.9.3
|
||||
|
@ -11,7 +11,7 @@ import java.util.Objects;
|
||||
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTException;
|
||||
import org.jglrxavpok.hephaistos.nbt.SNBTParser;
|
||||
import org.jglrxavpok.hephaistos.parser.SNBTParser;
|
||||
|
||||
/**
|
||||
* Adventure related constants, etc.
|
||||
|
@ -16,6 +16,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTException;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
final class NBTLegacyHoverEventSerializer implements LegacyHoverEventSerializer {
|
||||
static final NBTLegacyHoverEventSerializer INSTANCE = new NBTLegacyHoverEventSerializer();
|
||||
@ -66,17 +67,23 @@ final class NBTLegacyHoverEventSerializer implements LegacyHoverEventSerializer
|
||||
|
||||
@Override
|
||||
public @NotNull Component serializeShowItem(HoverEvent.@NotNull ShowItem input) throws IOException {
|
||||
final NBTCompound tag = new NBTCompound();
|
||||
tag.setString(ITEM_TYPE, input.item().asString());
|
||||
tag.setByte(ITEM_COUNT, (byte) input.count());
|
||||
AtomicReference<NBTException> exception = new AtomicReference<>(null);
|
||||
final NBTCompound tag = NBT.Compound(t -> {
|
||||
t.setString(ITEM_TYPE, input.item().asString());
|
||||
t.setByte(ITEM_COUNT, (byte) input.count());
|
||||
|
||||
final BinaryTagHolder nbt = input.nbt();
|
||||
if (nbt != null) {
|
||||
try {
|
||||
tag.set(ITEM_TAG, nbt.get(MinestomAdventure.NBT_CODEC));
|
||||
} catch (NBTException e) {
|
||||
throw new IOException(e);
|
||||
final BinaryTagHolder nbt = input.nbt();
|
||||
if (nbt != null) {
|
||||
try {
|
||||
t.set(ITEM_TAG, nbt.get(MinestomAdventure.NBT_CODEC));
|
||||
} catch (NBTException e) {
|
||||
exception.set(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(exception.get() != null) {
|
||||
throw new IOException(exception.get());
|
||||
}
|
||||
|
||||
return Component.text(MinestomAdventure.NBT_CODEC.encode(tag));
|
||||
@ -84,14 +91,15 @@ final class NBTLegacyHoverEventSerializer implements LegacyHoverEventSerializer
|
||||
|
||||
@Override
|
||||
public @NotNull Component serializeShowEntity(HoverEvent.@NotNull ShowEntity input, Codec.Encoder<Component, String, ? extends RuntimeException> componentEncoder) throws IOException {
|
||||
final NBTCompound tag = new NBTCompound();
|
||||
tag.setString(ENTITY_ID, input.id().toString());
|
||||
tag.setString(ENTITY_TYPE, input.type().asString());
|
||||
final NBTCompound tag = NBT.Compound(t -> {
|
||||
t.setString(ENTITY_ID, input.id().toString());
|
||||
t.setString(ENTITY_TYPE, input.type().asString());
|
||||
|
||||
final Component name = input.name();
|
||||
if (name != null) {
|
||||
tag.setString(ENTITY_NAME, componentEncoder.encode(name));
|
||||
}
|
||||
final Component name = input.name();
|
||||
if (name != null) {
|
||||
t.setString(ENTITY_NAME, componentEncoder.encode(name));
|
||||
}
|
||||
});
|
||||
|
||||
return Component.text(MinestomAdventure.NBT_CODEC.encode(tag));
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import net.minestom.server.tag.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -23,7 +24,7 @@ public class ConsoleSender implements CommandSender {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleSender.class);
|
||||
|
||||
private final Set<Permission> permissions = new CopyOnWriteArraySet<>();
|
||||
private final NBTCompound nbtCompound = new NBTCompound();
|
||||
private final MutableNBTCompound nbtCompound = new MutableNBTCompound();
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NotNull String message) {
|
||||
|
@ -7,6 +7,7 @@ import net.minestom.server.tag.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@ -22,7 +23,7 @@ import java.util.Set;
|
||||
public class ServerSender implements CommandSender {
|
||||
|
||||
private final Set<Permission> permissions = Collections.unmodifiableSet(new HashSet<>());
|
||||
private final NBTCompound nbtCompound = new NBTCompound();
|
||||
private final MutableNBTCompound nbtCompound = new MutableNBTCompound();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
|
@ -9,7 +9,7 @@ import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTException;
|
||||
import org.jglrxavpok.hephaistos.nbt.SNBTParser;
|
||||
import org.jglrxavpok.hephaistos.parser.SNBTParser;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
|
@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTException;
|
||||
import org.jglrxavpok.hephaistos.nbt.SNBTParser;
|
||||
import org.jglrxavpok.hephaistos.parser.SNBTParser;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
|
@ -7,7 +7,7 @@ import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTException;
|
||||
import org.jglrxavpok.hephaistos.nbt.SNBTParser;
|
||||
import org.jglrxavpok.hephaistos.parser.SNBTParser;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
|
@ -51,6 +51,7 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
@ -143,7 +144,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
||||
this instanceof Player player ? entity -> entity.viewEngine.viewableOption.addition.accept(player) : null,
|
||||
this instanceof Player player ? entity -> entity.viewEngine.viewableOption.removal.accept(player) : null);
|
||||
protected final Set<Player> viewers = viewEngine.asSet();
|
||||
private final NBTCompound nbtCompound = new NBTCompound();
|
||||
private final MutableNBTCompound nbtCompound = new MutableNBTCompound();
|
||||
private final Set<Permission> permissions = new CopyOnWriteArraySet<>();
|
||||
|
||||
protected UUID uuid;
|
||||
|
@ -161,7 +161,7 @@ public class Metadata {
|
||||
EMPTY_VALUES.set(TYPE_DIRECTION, Direction(Direction.DOWN));
|
||||
EMPTY_VALUES.set(TYPE_OPTUUID, OptUUID(null));
|
||||
EMPTY_VALUES.set(TYPE_OPTBLOCKID, OptBlockID(null));
|
||||
EMPTY_VALUES.set(TYPE_NBT, NBT(new NBTEnd()));
|
||||
EMPTY_VALUES.set(TYPE_NBT, NBT(NBTEnd.INSTANCE));
|
||||
//EMPTY_VALUES.set(TYPE_PARTICLE -> throw new UnsupportedOperationException();
|
||||
EMPTY_VALUES.set(TYPE_VILLAGERDATA, VillagerData(0, 0, 0));
|
||||
EMPTY_VALUES.set(TYPE_OPTVARINT, OptVarInt(null));
|
||||
|
@ -84,6 +84,7 @@ import org.jctools.queues.MpscUnboundedXaddArrayQueue;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -237,11 +238,12 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
public void UNSAFE_init(@NotNull Instance spawnInstance) {
|
||||
this.dimensionType = spawnInstance.getDimensionType();
|
||||
|
||||
NBTCompound nbt = new NBTCompound();
|
||||
NBTCompound dimensions = MinecraftServer.getDimensionTypeManager().toNBT();
|
||||
NBTCompound biomes = MinecraftServer.getBiomeManager().toNBT();
|
||||
nbt.set("minecraft:dimension_type", dimensions);
|
||||
nbt.set("minecraft:worldgen/biome", biomes);
|
||||
NBTCompound nbt = NBT.Compound(n -> {
|
||||
NBTCompound dimensions = MinecraftServer.getDimensionTypeManager().toNBT();
|
||||
NBTCompound biomes = MinecraftServer.getBiomeManager().toNBT();
|
||||
n.set("minecraft:dimension_type", dimensions);
|
||||
n.set("minecraft:worldgen/biome", biomes);
|
||||
});
|
||||
|
||||
final JoinGamePacket joinGamePacket = new JoinGamePacket(getEntityId(), gameMode.isHardcore(), gameMode, null,
|
||||
List.of("minestom:world"), nbt, dimensionType.toNBT(), dimensionType.getName().asString(),
|
||||
|
@ -10,6 +10,7 @@ import net.minestom.server.tag.TagHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
|
||||
/**
|
||||
* Represents a type of damage, required when calling {@link LivingEntity#damage(DamageType, float)}
|
||||
@ -29,7 +30,7 @@ public class DamageType implements TagHandler {
|
||||
};
|
||||
private final String identifier;
|
||||
private final Object nbtLock = new Object();
|
||||
private final NBTCompound nbt = new NBTCompound();
|
||||
private final MutableNBTCompound nbt = new MutableNBTCompound();
|
||||
|
||||
/**
|
||||
* Creates a new damage type.
|
||||
|
@ -470,7 +470,7 @@ public class ExtensionManager {
|
||||
|
||||
// While there are entries with no more elements (no more dependencies)
|
||||
while (!(
|
||||
loadableExtensions = dependencyMap.entrySet().stream().filter(entry -> isLoaded(entry.getValue())).collect(Collectors.toList())
|
||||
loadableExtensions = dependencyMap.entrySet().stream().filter(entry -> isLoaded(entry.getValue())).toList()
|
||||
).isEmpty()
|
||||
) {
|
||||
// Get all "loadable" (not actually being loaded!) extensions and put them in the sorted list.
|
||||
|
@ -6,6 +6,7 @@ import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.instance.block.BlockManager;
|
||||
import net.minestom.server.tag.Tag;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import net.minestom.server.utils.async.AsyncUtils;
|
||||
import net.minestom.server.world.biomes.Biome;
|
||||
import net.minestom.server.world.biomes.BiomeManager;
|
||||
@ -13,6 +14,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.mca.*;
|
||||
import org.jglrxavpok.hephaistos.nbt.*;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -22,8 +24,7 @@ import java.io.RandomAccessFile;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@ -87,20 +88,31 @@ public class AnvilLoader implements IChunkLoader {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
|
||||
Chunk chunk = new DynamicChunk(instance, chunkX, chunkZ);
|
||||
// TODO Biomes
|
||||
// TODO: Parallelize block, block entities and biome loading
|
||||
|
||||
if (fileChunk.getGenerationStatus().compareTo(ChunkColumn.GenerationStatus.Biomes) > 0) {
|
||||
final int[] fileChunkBiomes = fileChunk.getBiomes();
|
||||
for (int id : fileChunkBiomes) {
|
||||
// ((y >> 2) & 63) << 4 | ((z >> 2) & 3) << 2 | ((x >> 2) & 3)
|
||||
final Biome biome = Objects.requireNonNullElse(BIOME_MANAGER.getById(id), BIOME);
|
||||
chunk.setBiome(0, 0, 0, biome);
|
||||
HashMap<String, Biome> biomeCache = new HashMap<>();
|
||||
|
||||
for (ChunkSection section : fileChunk.getSections().values()) {
|
||||
for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) {
|
||||
for (int z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
|
||||
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
|
||||
int finalX = fileChunk.getX() * Chunk.CHUNK_SIZE_X + x;
|
||||
int finalZ = fileChunk.getZ() * Chunk.CHUNK_SIZE_Z + z;
|
||||
int finalY = section.getY() * Chunk.CHUNK_SECTION_SIZE + y;
|
||||
String biomeName = section.getBiome(x, y, z);
|
||||
Biome biome = biomeCache.computeIfAbsent(biomeName, n -> Objects.requireNonNullElse(BIOME_MANAGER.getByName(NamespaceID.from(n)), BIOME));
|
||||
chunk.setBiome(finalX, finalY, finalZ, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Blocks
|
||||
loadBlocks(chunk, fileChunk);
|
||||
loadTileEntities(chunk, fileChunk);
|
||||
// Lights
|
||||
for (var chunkSection : fileChunk.getSections()) {
|
||||
for (var chunkSection : fileChunk.getSections().values()) {
|
||||
Section section = chunk.getSection(chunkSection.getY());
|
||||
section.setSkyLight(chunkSection.getSkyLights());
|
||||
section.setBlockLight(chunkSection.getBlockLights());
|
||||
@ -127,7 +139,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
}
|
||||
|
||||
private void loadBlocks(Chunk chunk, ChunkColumn fileChunk) {
|
||||
for (var section : fileChunk.getSections()) {
|
||||
for (var section : fileChunk.getSections().values()) {
|
||||
if (section.getEmpty()) continue;
|
||||
final int yOffset = Chunk.CHUNK_SECTION_SIZE * section.getY();
|
||||
for (int x = 0; x < Chunk.CHUNK_SECTION_SIZE; x++) {
|
||||
@ -172,12 +184,15 @@ public class AnvilLoader implements IChunkLoader {
|
||||
block = block.withHandler(handler);
|
||||
}
|
||||
// Remove anvil tags
|
||||
te.removeTag("id")
|
||||
.removeTag("x").removeTag("y").removeTag("z")
|
||||
.removeTag("keepPacked");
|
||||
MutableNBTCompound mutableCopy = te.toMutableCompound();
|
||||
mutableCopy.remove("id");
|
||||
mutableCopy.remove("x");
|
||||
mutableCopy.remove("y");
|
||||
mutableCopy.remove("z");
|
||||
mutableCopy.remove("keepPacked");
|
||||
// Place block
|
||||
final var finalBlock = te.getSize() > 0 ?
|
||||
block.withNbt(te) : block;
|
||||
final var finalBlock = mutableCopy.getSize() > 0 ?
|
||||
block.withNbt(mutableCopy.toCompound()) : block;
|
||||
loadedChunk.setBlock(x, y, z, finalBlock);
|
||||
}
|
||||
}
|
||||
@ -247,7 +262,7 @@ public class AnvilLoader implements IChunkLoader {
|
||||
}
|
||||
|
||||
private void save(Chunk chunk, ChunkColumn chunkColumn) {
|
||||
NBTList<NBTCompound> tileEntities = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
List<NBTCompound> tileEntities = new ArrayList<>();
|
||||
chunkColumn.setGenerationStatus(ChunkColumn.GenerationStatus.Full);
|
||||
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
|
||||
for (int z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
|
||||
@ -255,13 +270,15 @@ public class AnvilLoader implements IChunkLoader {
|
||||
final Block block = chunk.getBlock(x, y, z);
|
||||
// Block
|
||||
chunkColumn.setBlockState(x, y, z, new BlockState(block.name(), block.properties()));
|
||||
chunkColumn.setBiome(x, 0, z, chunk.getBiome(x, y, z).id());
|
||||
chunkColumn.setBiome(x, 0, z, chunk.getBiome(x, y, z).name().asString());
|
||||
|
||||
// Tile entity
|
||||
var nbt = block.nbt();
|
||||
final BlockHandler handler = block.handler();
|
||||
if (nbt != null || handler != null) {
|
||||
nbt = Objects.requireNonNullElseGet(nbt, NBTCompound::new);
|
||||
var originalNBT = block.nbt();
|
||||
if (originalNBT != null || handler != null) {
|
||||
MutableNBTCompound nbt = originalNBT != null ?
|
||||
originalNBT.toMutableCompound() : new MutableNBTCompound();
|
||||
|
||||
if (handler != null) {
|
||||
nbt.setString("id", handler.getNamespaceId().asString());
|
||||
}
|
||||
@ -269,12 +286,12 @@ public class AnvilLoader implements IChunkLoader {
|
||||
nbt.setInt("y", y);
|
||||
nbt.setInt("z", z + Chunk.CHUNK_SIZE_Z * chunk.getChunkZ());
|
||||
nbt.setByte("keepPacked", (byte) 0);
|
||||
tileEntities.add(nbt);
|
||||
tileEntities.add(nbt.toCompound());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chunkColumn.setTileEntities(tileEntities);
|
||||
chunkColumn.setTileEntities(NBT.List(NBTType.TAG_Compound, tileEntities));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -17,6 +17,7 @@ import net.minestom.server.world.biomes.Biome;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@ -55,7 +56,7 @@ public abstract class Chunk implements Block.Getter, Block.Setter, Biome.Getter,
|
||||
protected PFColumnarSpace columnarSpace;
|
||||
|
||||
// Data
|
||||
private final NBTCompound nbt = new NBTCompound();
|
||||
private final MutableNBTCompound nbt = new MutableNBTCompound();
|
||||
|
||||
public Chunk(@NotNull Instance instance, int chunkX, int chunkZ, boolean shouldGenerate) {
|
||||
this.identifier = UUID.randomUUID();
|
||||
|
@ -22,6 +22,7 @@ import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.world.biomes.Biome;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.*;
|
||||
@ -47,7 +48,7 @@ public class DynamicChunk extends Chunk {
|
||||
public DynamicChunk(@NotNull Instance instance, int chunkX, int chunkZ) {
|
||||
super(instance, chunkX, chunkZ, true);
|
||||
this.minSection = instance.getDimensionType().getMinY() / CHUNK_SECTION_SIZE;
|
||||
this.maxSection = instance.getDimensionType().getHeight() / CHUNK_SECTION_SIZE;
|
||||
this.maxSection = (instance.getDimensionType().getMinY() + instance.getDimensionType().getHeight()) / CHUNK_SECTION_SIZE;
|
||||
this.sections = new Section[maxSection - minSection];
|
||||
Arrays.setAll(sections, value -> new Section());
|
||||
}
|
||||
@ -121,7 +122,7 @@ public class DynamicChunk extends Chunk {
|
||||
}
|
||||
}
|
||||
// Retrieve the block from state id
|
||||
final Section section = sections[ChunkUtils.getSectionAt(y) + minSection];
|
||||
final Section section = sections[ChunkUtils.getSectionAt(y) - minSection];
|
||||
final int blockStateId = section.blockPalette()
|
||||
.get(toChunkRelativeCoordinate(x), y, toChunkRelativeCoordinate(z));
|
||||
if (blockStateId == -1) return Block.AIR; // Section is empty
|
||||
@ -130,7 +131,7 @@ public class DynamicChunk extends Chunk {
|
||||
|
||||
@Override
|
||||
public @NotNull Biome getBiome(int x, int y, int z) {
|
||||
final Section section = sections[ChunkUtils.getSectionAt(y) + minSection];
|
||||
final Section section = sections[ChunkUtils.getSectionAt(y) - minSection];
|
||||
final int id = section.biomePalette()
|
||||
.get(toChunkRelativeCoordinate(x) / 4, y / 4, toChunkRelativeCoordinate(z) / 4);
|
||||
return MinecraftServer.getBiomeManager().getById(id);
|
||||
@ -186,9 +187,9 @@ public class DynamicChunk extends Chunk {
|
||||
}
|
||||
}
|
||||
final int bitsForHeight = MathUtils.bitsToRepresent(dimensionHeight);
|
||||
heightmapsNBT = new NBTCompound()
|
||||
.setLongArray("MOTION_BLOCKING", Utils.encodeBlocks(motionBlocking, bitsForHeight))
|
||||
.setLongArray("WORLD_SURFACE", Utils.encodeBlocks(worldSurface, bitsForHeight));
|
||||
heightmapsNBT = NBT.Compound(Map.of(
|
||||
"MOTION_BLOCKING", NBT.LongArray(Utils.encodeBlocks(motionBlocking, bitsForHeight)),
|
||||
"WORLD_SURFACE", NBT.LongArray(Utils.encodeBlocks(worldSurface, bitsForHeight))));
|
||||
}
|
||||
// Data
|
||||
final BinaryWriter writer = new BinaryWriter();
|
||||
|
@ -32,6 +32,7 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
@ -84,7 +85,7 @@ public abstract class Instance implements Block.Getter, Block.Setter, Tickable,
|
||||
|
||||
// instance custom data
|
||||
private final Object nbtLock = new Object();
|
||||
private final NBTCompound nbt = new NBTCompound();
|
||||
private final MutableNBTCompound nbt = new MutableNBTCompound();
|
||||
|
||||
// the explosion supplier
|
||||
private ExplosionSupplier explosionSupplier;
|
||||
|
@ -9,6 +9,7 @@ import net.minestom.server.utils.block.BlockUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
@ -105,9 +106,9 @@ final class BlockImpl implements Block {
|
||||
|
||||
@Override
|
||||
public @NotNull <T> Block withTag(@NotNull Tag<T> tag, @Nullable T value) {
|
||||
var temporaryNbt = nbt != null ? nbt.deepClone() : new NBTCompound();
|
||||
var temporaryNbt = new MutableNBTCompound(Objects.requireNonNullElse(nbt, NBTCompound.EMPTY));
|
||||
tag.write(temporaryNbt, value);
|
||||
final var finalNbt = temporaryNbt.getSize() > 0 ? NBT_CACHE.get(temporaryNbt, Function.identity()) : null;
|
||||
final var finalNbt = temporaryNbt.getSize() > 0 ? NBT_CACHE.get(temporaryNbt.toCompound(), Function.identity()) : null;
|
||||
return new BlockImpl(registry, propertyEntry, properties, finalNbt, handler);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -32,7 +33,7 @@ public sealed abstract class AbstractInventory implements InventoryClickHandler,
|
||||
protected final InventoryClickProcessor clickProcessor = new InventoryClickProcessor();
|
||||
|
||||
private final Object nbtLock = new Object();
|
||||
private final NBTCompound nbt = new NBTCompound();
|
||||
private final MutableNBTCompound nbt = new MutableNBTCompound();
|
||||
|
||||
protected AbstractInventory(int size) {
|
||||
this.size = size;
|
||||
|
@ -119,7 +119,7 @@ public class ItemMeta implements TagReadable, Writeable {
|
||||
}
|
||||
|
||||
public @NotNull NBTCompound toNBT() {
|
||||
return nbt.deepClone();
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public @NotNull String toSNBT() {
|
||||
|
@ -12,6 +12,7 @@ import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.*;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||
@ -75,7 +76,7 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
final String name = GsonComponentSerializer.gson().serialize(displayName);
|
||||
nbtCompound.setString("Name", name);
|
||||
} else {
|
||||
nbtCompound.removeTag("Name");
|
||||
nbtCompound.remove("Name");
|
||||
}
|
||||
});
|
||||
return this;
|
||||
@ -85,10 +86,11 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
public @NotNull ItemMetaBuilder lore(@NotNull List<@NotNull Component> lore) {
|
||||
this.lore = new ArrayList<>(lore);
|
||||
handleCompound("display", nbtCompound -> {
|
||||
final NBTList<NBTString> loreNBT = new NBTList<>(NBTTypes.TAG_String);
|
||||
for (Component line : lore) {
|
||||
loreNBT.add(new NBTString(GsonComponentSerializer.gson().serialize(line)));
|
||||
}
|
||||
final NBTList<NBTString> loreNBT = NBT.List(NBTType.TAG_String,
|
||||
lore.stream()
|
||||
.map(line -> new NBTString(GsonComponentSerializer.gson().serialize(line)))
|
||||
.toList()
|
||||
);
|
||||
nbtCompound.set("Lore", loreNBT);
|
||||
});
|
||||
return this;
|
||||
@ -104,8 +106,9 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
public @NotNull ItemMetaBuilder enchantments(@NotNull Map<Enchantment, Short> enchantments) {
|
||||
this.enchantmentMap = new HashMap<>(enchantments);
|
||||
handleMap(enchantmentMap, "Enchantments", () -> {
|
||||
NBTUtils.writeEnchant(nbt, "Enchantments", enchantmentMap);
|
||||
return nbt.get("Enchantments");
|
||||
MutableNBTCompound mutableCopy = new MutableNBTCompound(nbt);
|
||||
NBTUtils.writeEnchant(mutableCopy, "Enchantments", enchantmentMap);
|
||||
return mutableCopy.get("Enchantments");
|
||||
});
|
||||
return this;
|
||||
}
|
||||
@ -127,22 +130,19 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
@Contract("_ -> this")
|
||||
public @NotNull ItemMetaBuilder attributes(@NotNull List<@NotNull ItemAttribute> attributes) {
|
||||
this.attributes = new ArrayList<>(attributes);
|
||||
handleCollection(attributes, "AttributeModifiers", () -> {
|
||||
NBTList<NBTCompound> attributesNBT = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
for (ItemAttribute itemAttribute : attributes) {
|
||||
final UUID uuid = itemAttribute.getUuid();
|
||||
attributesNBT.add(
|
||||
new NBTCompound()
|
||||
.setIntArray("UUID", Utils.uuidToIntArray(uuid))
|
||||
.setDouble("Amount", itemAttribute.getValue())
|
||||
.setString("Slot", itemAttribute.getSlot().name().toLowerCase())
|
||||
.setString("AttributeName", itemAttribute.getAttribute().getKey())
|
||||
.setInt("Operation", itemAttribute.getOperation().getId())
|
||||
.setString("Name", itemAttribute.getInternalName())
|
||||
);
|
||||
}
|
||||
return attributesNBT;
|
||||
});
|
||||
|
||||
handleCollection(attributes, "AttributeModifiers", () -> NBT.List(
|
||||
NBTType.TAG_Compound,
|
||||
attributes.stream()
|
||||
.map(itemAttribute -> NBT.Compound(Map.of(
|
||||
"UUID", NBT.IntArray(Utils.uuidToIntArray(itemAttribute.getUuid())),
|
||||
"Amount", NBT.Double(itemAttribute.getValue()),
|
||||
"Slot", NBT.String(itemAttribute.getSlot().name().toLowerCase()),
|
||||
"AttributeName", NBT.String(itemAttribute.getAttribute().getKey()),
|
||||
"Operation", NBT.Int(itemAttribute.getOperation().getId()),
|
||||
"Name", NBT.String(itemAttribute.getInternalName()))))
|
||||
.toList()
|
||||
));
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -157,11 +157,12 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
@Contract("_ -> this")
|
||||
public @NotNull ItemMetaBuilder canPlaceOn(@NotNull Set<@NotNull Block> blocks) {
|
||||
this.canPlaceOn = new HashSet<>(blocks);
|
||||
handleCollection(canPlaceOn, "CanPlaceOn", () -> {
|
||||
NBTList<NBTString> list = new NBTList<>(NBTTypes.TAG_String);
|
||||
canPlaceOn.forEach(block -> list.add(new NBTString(block.name())));
|
||||
return list;
|
||||
});
|
||||
handleCollection(canPlaceOn, "CanPlaceOn", () -> NBT.List(
|
||||
NBTType.TAG_String,
|
||||
canPlaceOn.stream()
|
||||
.map(block -> new NBTString(block.name()))
|
||||
.toList()
|
||||
));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -173,11 +174,12 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
@Contract("_ -> this")
|
||||
public @NotNull ItemMetaBuilder canDestroy(@NotNull Set<@NotNull Block> blocks) {
|
||||
this.canDestroy = new HashSet<>(blocks);
|
||||
handleCollection(canDestroy, "CanDestroy", () -> {
|
||||
NBTList<NBTString> list = new NBTList<>(NBTTypes.TAG_String);
|
||||
canDestroy.forEach(block -> list.add(new NBTString(block.name())));
|
||||
return list;
|
||||
});
|
||||
handleCollection(canPlaceOn, "CanPlaceOn", () -> NBT.List(
|
||||
NBTType.TAG_String,
|
||||
canDestroy.stream()
|
||||
.map(block -> new NBTString(block.name()))
|
||||
.toList()
|
||||
));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -203,13 +205,16 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
|
||||
protected abstract @NotNull Supplier<@NotNull ItemMetaBuilder> getSupplier();
|
||||
|
||||
protected synchronized void mutateNbt(Consumer<NBTCompound> consumer) {
|
||||
protected synchronized void mutateNbt(Consumer<MutableNBTCompound> consumer) {
|
||||
MutableNBTCompound copy = new MutableNBTCompound(nbt);
|
||||
consumer.accept(copy);
|
||||
if (built) {
|
||||
built = false;
|
||||
final var currentNbt = nbt;
|
||||
NBT_UPDATER.compareAndSet(this, currentNbt, currentNbt.deepClone());
|
||||
NBT_UPDATER.compareAndSet(this, currentNbt, copy.toCompound());
|
||||
} else {
|
||||
nbt = copy.toCompound();
|
||||
}
|
||||
consumer.accept(nbt);
|
||||
}
|
||||
|
||||
protected synchronized NBTCompound nbt() {
|
||||
@ -222,28 +227,16 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
}
|
||||
|
||||
protected void handleCompound(@NotNull String key,
|
||||
@NotNull Consumer<@NotNull NBTCompound> consumer) {
|
||||
@NotNull Consumer<@NotNull MutableNBTCompound> consumer) {
|
||||
mutateNbt(nbt -> {
|
||||
NBTCompound compound = null;
|
||||
boolean newNbt = false;
|
||||
if (nbt.containsKey(key)) {
|
||||
NBT dNbt = nbt.get(key);
|
||||
if (dNbt instanceof NBTCompound) {
|
||||
compound = (NBTCompound) dNbt;
|
||||
}
|
||||
MutableNBTCompound compoundToModify = nbt.get(key) instanceof NBTCompound compound ?
|
||||
compound.toMutableCompound() : new MutableNBTCompound();
|
||||
|
||||
consumer.accept(compoundToModify);
|
||||
if (compoundToModify.isEmpty()) {
|
||||
nbt.remove(key);
|
||||
} else {
|
||||
compound = new NBTCompound();
|
||||
newNbt = true;
|
||||
}
|
||||
|
||||
if (compound != null) {
|
||||
consumer.accept(compound);
|
||||
|
||||
if (newNbt && compound.getSize() > 0) {
|
||||
this.nbt.set(key, compound);
|
||||
} else if (!newNbt && compound.getSize() == 0) {
|
||||
this.nbt.removeTag(key);
|
||||
}
|
||||
nbt.set(key, compoundToModify.toCompound());
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -255,7 +248,7 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
if (value != null) {
|
||||
compound.set(key, supplier.get());
|
||||
} else {
|
||||
compound.removeTag(key);
|
||||
compound.remove(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -267,7 +260,7 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
if (!objects.isEmpty()) {
|
||||
compound.set(key, supplier.get());
|
||||
} else {
|
||||
compound.removeTag(key);
|
||||
compound.remove(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -279,7 +272,7 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
if (!objects.isEmpty()) {
|
||||
compound.set(key, supplier.get());
|
||||
} else {
|
||||
compound.removeTag(key);
|
||||
compound.remove(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -287,7 +280,7 @@ public abstract class ItemMetaBuilder implements TagWritable {
|
||||
@Contract(value = "_, _ -> new", pure = true)
|
||||
public static @NotNull ItemMetaBuilder fromNBT(@NotNull ItemMetaBuilder src, @NotNull NBTCompound nbtCompound) {
|
||||
ItemMetaBuilder dest = src.getSupplier().get();
|
||||
dest.nbt = nbtCompound.deepClone();
|
||||
dest.nbt = nbtCompound;
|
||||
NBTUtils.loadDataIntoMeta(dest, dest.nbt);
|
||||
return dest;
|
||||
}
|
||||
|
@ -12,9 +12,11 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
@ -254,11 +256,10 @@ public final class ItemStack implements TagReadable, HoverEventSource<HoverEvent
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public @NotNull NBTCompound toItemNBT() {
|
||||
final NBTCompound nbtCompound = new NBTCompound();
|
||||
nbtCompound.setString("id", getMaterial().name());
|
||||
nbtCompound.setByte("Count", (byte) getAmount());
|
||||
nbtCompound.set("tag", getMeta().toNBT());
|
||||
return nbtCompound;
|
||||
return NBT.Compound(Map.of(
|
||||
"id", NBT.String(getMaterial().name()),
|
||||
"Count", NBT.Byte(getAmount()),
|
||||
"tag", getMeta().toNBT()));
|
||||
}
|
||||
|
||||
@Contract(value = "-> new", pure = true)
|
||||
|
@ -2,6 +2,8 @@ package net.minestom.server.item.firework;
|
||||
|
||||
import net.minestom.server.color.Color;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.collections.ImmutableIntArray;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -47,14 +49,14 @@ public class FireworkEffect {
|
||||
List<Color> secondaryColor = new ArrayList<>();
|
||||
|
||||
if (compound.containsKey("Colors")) {
|
||||
final int[] color = compound.getIntArray("Colors");
|
||||
ImmutableIntArray color = compound.getIntArray("Colors");
|
||||
for (int j : color) {
|
||||
primaryColor.add(new Color(j));
|
||||
}
|
||||
}
|
||||
|
||||
if (compound.containsKey("FadeColors")) {
|
||||
final int[] fadeColor = compound.getIntArray("FadeColors");
|
||||
ImmutableIntArray fadeColor = compound.getIntArray("FadeColors");
|
||||
for (int j : fadeColor) {
|
||||
secondaryColor.add(new Color(j));
|
||||
}
|
||||
@ -137,15 +139,14 @@ public class FireworkEffect {
|
||||
* @return The firework effect as a nbt compound.
|
||||
*/
|
||||
public NBTCompound asCompound() {
|
||||
NBTCompound explosionCompound = new NBTCompound();
|
||||
explosionCompound.setByte("Flicker", this.getFlicker());
|
||||
explosionCompound.setByte("Trail", this.getTrail());
|
||||
explosionCompound.setByte("Type", this.getType());
|
||||
return NBT.Compound(explosionCompound -> {
|
||||
explosionCompound.setByte("Flicker", this.getFlicker());
|
||||
explosionCompound.setByte("Trail", this.getTrail());
|
||||
explosionCompound.setByte("Type", this.getType());
|
||||
|
||||
explosionCompound.setIntArray("Colors", this.getColors());
|
||||
explosionCompound.setIntArray("FadeColors", this.getFadeColors());
|
||||
|
||||
return explosionCompound;
|
||||
explosionCompound.setIntArray("Colors", this.getColors());
|
||||
explosionCompound.setIntArray("FadeColors", this.getFadeColors());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,9 +5,7 @@ import net.minestom.server.item.ItemMetaBuilder;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
import org.jglrxavpok.hephaistos.nbt.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -58,11 +56,7 @@ public class BundleMeta extends ItemMeta implements ItemMetaBuilder.Provider<Bun
|
||||
|
||||
private void updateItems() {
|
||||
mutateNbt(compound -> {
|
||||
NBTList<NBTCompound> itemList = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
for (ItemStack item : items) {
|
||||
itemList.add(item.toItemNBT());
|
||||
}
|
||||
compound.set("Items", itemList);
|
||||
compound.set("Items", NBT.List(NBTType.TAG_Compound, items.size(), i -> items.get(i).toItemNBT()));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import net.minestom.server.item.ItemMeta;
|
||||
import net.minestom.server.item.ItemMetaBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
@ -57,7 +58,7 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
|
||||
if (lodestoneDimension != null) {
|
||||
compound.setString("LodestoneDimension", lodestoneDimension);
|
||||
} else {
|
||||
compound.removeTag("LodestoneDimension");
|
||||
compound.remove("LodestoneDimension");
|
||||
}
|
||||
});
|
||||
|
||||
@ -69,13 +70,13 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider<Co
|
||||
|
||||
mutateNbt(compound -> {
|
||||
if (lodestonePosition != null) {
|
||||
NBTCompound posCompound = new NBTCompound();
|
||||
posCompound.setInt("X", lodestonePosition.blockX());
|
||||
posCompound.setInt("Y", lodestonePosition.blockY());
|
||||
posCompound.setInt("Z", lodestonePosition.blockZ());
|
||||
compound.set("LodestonePos", posCompound);
|
||||
compound.set("LodestonePos", NBT.Compound(posCompound -> {
|
||||
posCompound.setInt("X", lodestonePosition.blockX());
|
||||
posCompound.setInt("Y", lodestonePosition.blockY());
|
||||
posCompound.setInt("Z", lodestonePosition.blockZ());
|
||||
}));
|
||||
} else {
|
||||
compound.removeTag("LodestonePos");
|
||||
compound.remove("LodestonePos");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -6,9 +6,10 @@ import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -94,11 +95,9 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider<S
|
||||
this.projectile1 = projectile;
|
||||
this.triple = false;
|
||||
|
||||
NBTList<NBTCompound> chargedProjectiles = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
if (!projectile.isAir()) {
|
||||
chargedProjectiles.add(getItemCompound(projectile));
|
||||
}
|
||||
mutateNbt(compound -> compound.set("ChargedProjectiles", chargedProjectiles));
|
||||
List<NBTCompound> chargedProjectiles =
|
||||
projectile.isAir() ? List.of() : List.of(getItemCompound(projectile));
|
||||
mutateNbt(compound -> compound.set("ChargedProjectiles", NBT.List(NBTType.TAG_Compound, chargedProjectiles)));
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -120,11 +119,9 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider<S
|
||||
this.projectile3 = projectile3;
|
||||
this.triple = true;
|
||||
|
||||
NBTList<NBTCompound> chargedProjectiles = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
chargedProjectiles.add(getItemCompound(projectile1));
|
||||
chargedProjectiles.add(getItemCompound(projectile2));
|
||||
chargedProjectiles.add(getItemCompound(projectile3));
|
||||
mutateNbt(compound -> compound.set("ChargedProjectiles", chargedProjectiles));
|
||||
List<NBTCompound> chargedProjectiles =
|
||||
List.of(getItemCompound(projectile1), getItemCompound(projectile2), getItemCompound(projectile3));
|
||||
mutateNbt(compound -> compound.set("ChargedProjectiles", NBT.List(NBTType.TAG_Compound, chargedProjectiles)));
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -181,9 +178,10 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider<S
|
||||
|
||||
private @NotNull NBTCompound getItemCompound(@NotNull ItemStack itemStack) {
|
||||
NBTCompound compound = itemStack.getMeta().toNBT();
|
||||
compound.setByte("Count", (byte) itemStack.getAmount());
|
||||
compound.setString("id", itemStack.getMaterial().name());
|
||||
return compound;
|
||||
return compound.modify(n -> {
|
||||
n.setByte("Count", (byte) itemStack.getAmount());
|
||||
n.setString("id", itemStack.getMaterial().name());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -4,15 +4,17 @@ import net.minestom.server.item.ItemMeta;
|
||||
import net.minestom.server.item.ItemMetaBuilder;
|
||||
import net.minestom.server.item.firework.FireworkEffect;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FireworkMeta extends ItemMeta implements ItemMetaBuilder.Provider<FireworkMeta.Builder> {
|
||||
|
||||
@ -42,11 +44,12 @@ public class FireworkMeta extends ItemMeta implements ItemMetaBuilder.Provider<F
|
||||
public Builder effects(List<FireworkEffect> effects) {
|
||||
this.effects = effects;
|
||||
handleCompound("Fireworks", nbtCompound -> {
|
||||
NBTList<NBTCompound> explosions = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
for (FireworkEffect effect : this.effects) {
|
||||
explosions.add(effect.asCompound());
|
||||
}
|
||||
nbtCompound.set("Explosions", explosions);
|
||||
nbtCompound.set("Explosions", NBT.List(
|
||||
NBTType.TAG_Compound,
|
||||
effects.stream()
|
||||
.map(FireworkEffect::asCompound)
|
||||
.toList()
|
||||
));
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class LeatherArmorMeta extends ItemMeta implements ItemMetaBuilder.Provid
|
||||
if (color != null) {
|
||||
nbtCompound.setInt("color", color.asRGB());
|
||||
} else {
|
||||
nbtCompound.removeTag("color");
|
||||
nbtCompound.remove("color");
|
||||
}
|
||||
});
|
||||
return this;
|
||||
|
@ -6,12 +6,14 @@ import net.minestom.server.item.ItemMeta;
|
||||
import net.minestom.server.item.ItemMetaBuilder;
|
||||
import net.minestom.server.utils.clone.PublicCloneable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@ -92,17 +94,17 @@ public class MapMeta extends ItemMeta implements ItemMetaBuilder.Provider<MapMet
|
||||
public Builder decorations(List<MapDecoration> value) {
|
||||
this.decorations = new ArrayList<>(value);
|
||||
|
||||
NBTList<NBTCompound> decorationsList = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
for (MapDecoration decoration : decorations) {
|
||||
NBTCompound decorationCompound = new NBTCompound();
|
||||
decorationCompound.setString("id", decoration.getId());
|
||||
decorationCompound.setByte("type", decoration.getType());
|
||||
decorationCompound.setByte("x", decoration.getX());
|
||||
decorationCompound.setByte("z", decoration.getZ());
|
||||
decorationCompound.setDouble("rot", decoration.getRotation());
|
||||
|
||||
decorationsList.add(decorationCompound);
|
||||
}
|
||||
NBTList<NBTCompound> decorationsList = NBT.List(
|
||||
NBTType.TAG_Compound,
|
||||
decorations.stream()
|
||||
.map(decoration -> NBT.Compound(Map.of(
|
||||
"id", NBT.String(decoration.getId()),
|
||||
"type", NBT.Byte(decoration.getType()),
|
||||
"x", NBT.Byte(decoration.getX()),
|
||||
"z", NBT.Byte(decoration.getZ()),
|
||||
"rot", NBT.Double(decoration.getRotation()))))
|
||||
.toList()
|
||||
);
|
||||
mutateNbt(compound -> compound.set("Decorations", decorationsList));
|
||||
|
||||
return this;
|
||||
@ -111,14 +113,7 @@ public class MapMeta extends ItemMeta implements ItemMetaBuilder.Provider<MapMet
|
||||
public Builder mapColor(Color value) {
|
||||
this.mapColor = value;
|
||||
|
||||
mutateNbt(nbt -> {
|
||||
NBTCompound displayCompound;
|
||||
if (nbt.containsKey("display")) {
|
||||
displayCompound = nbt.getCompound("display");
|
||||
} else {
|
||||
displayCompound = new NBTCompound();
|
||||
nbt.set("display", displayCompound);
|
||||
}
|
||||
handleCompound("display", displayCompound -> {
|
||||
displayCompound.setInt("MapColor", mapColor.asRGB());
|
||||
});
|
||||
|
||||
|
@ -6,10 +6,13 @@ import net.minestom.server.item.ItemMetaBuilder;
|
||||
import net.minestom.server.utils.Utils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
@ -50,15 +53,17 @@ public class PlayerHeadMeta extends ItemMeta implements ItemMetaBuilder.Provider
|
||||
this.playerSkin = playerSkin;
|
||||
handleCompound("SkullOwner", nbtCompound -> {
|
||||
if (playerSkin == null) {
|
||||
nbtCompound.removeTag("Properties");
|
||||
nbtCompound.remove("Properties");
|
||||
return;
|
||||
}
|
||||
|
||||
NBTList<NBTCompound> textures = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
final String value = Objects.requireNonNullElse(this.playerSkin.textures(), "");
|
||||
final String signature = Objects.requireNonNullElse(this.playerSkin.signature(), "");
|
||||
textures.add(new NBTCompound().setString("Value", value).setString("Signature", signature));
|
||||
nbtCompound.set("Properties", new NBTCompound().set("textures", textures));
|
||||
NBTList<NBTCompound> textures = new NBTList<>(NBTType.TAG_Compound,
|
||||
List.of(NBT.Compound(Map.of(
|
||||
"Value", NBT.String(value),
|
||||
"Signature", NBT.String(signature)))));
|
||||
nbtCompound.set("Properties", NBT.Compound(Map.of("textures", textures)));
|
||||
});
|
||||
return this;
|
||||
}
|
||||
@ -74,7 +79,7 @@ public class PlayerHeadMeta extends ItemMeta implements ItemMetaBuilder.Provider
|
||||
NBTCompound skullOwnerCompound = nbtCompound.getCompound("SkullOwner");
|
||||
|
||||
if (skullOwnerCompound.containsKey("Id")) {
|
||||
skullOwner(Utils.intArrayToUuid(skullOwnerCompound.getIntArray("Id")));
|
||||
skullOwner(Utils.intArrayToUuid(skullOwnerCompound.getIntArray("Id").copyArray()));
|
||||
}
|
||||
|
||||
if (skullOwnerCompound.containsKey("Properties")) {
|
||||
|
@ -7,14 +7,16 @@ import net.minestom.server.potion.CustomPotionEffect;
|
||||
import net.minestom.server.potion.PotionType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTType;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PotionMeta extends ItemMeta implements ItemMetaBuilder.Provider<PotionMeta.Builder> {
|
||||
|
||||
@ -58,18 +60,19 @@ public class PotionMeta extends ItemMeta implements ItemMetaBuilder.Provider<Pot
|
||||
public Builder effects(@NotNull List<CustomPotionEffect> customPotionEffects) {
|
||||
this.customPotionEffects = customPotionEffects;
|
||||
|
||||
NBTList<NBTCompound> potionList = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
for (CustomPotionEffect customPotionEffect : customPotionEffects) {
|
||||
NBTCompound potionCompound = new NBTCompound();
|
||||
potionCompound.setByte("Id", customPotionEffect.getId());
|
||||
potionCompound.setByte("Amplifier", customPotionEffect.getAmplifier());
|
||||
potionCompound.setInt("Duration", customPotionEffect.getDuration());
|
||||
potionCompound.setByte("Ambient", (byte) (customPotionEffect.isAmbient() ? 1 : 0));
|
||||
potionCompound.setByte("ShowParticles", (byte) (customPotionEffect.showParticles() ? 1 : 0));
|
||||
potionCompound.setByte("ShowIcon", (byte) (customPotionEffect.showIcon() ? 1 : 0));
|
||||
|
||||
potionList.add(potionCompound);
|
||||
}
|
||||
NBTList<NBTCompound> potionList = NBT.List(
|
||||
NBTType.TAG_Compound,
|
||||
customPotionEffects.stream()
|
||||
.map(customPotionEffect -> NBT.Compound(potionCompound -> {
|
||||
potionCompound.setByte("Id", customPotionEffect.getId());
|
||||
potionCompound.setByte("Amplifier", customPotionEffect.getAmplifier());
|
||||
potionCompound.setInt("Duration", customPotionEffect.getDuration());
|
||||
potionCompound.setByte("Ambient", (byte) (customPotionEffect.isAmbient() ? 1 : 0));
|
||||
potionCompound.setByte("ShowParticles", (byte) (customPotionEffect.showParticles() ? 1 : 0));
|
||||
potionCompound.setByte("ShowIcon", (byte) (customPotionEffect.showIcon() ? 1 : 0));
|
||||
}))
|
||||
.toList()
|
||||
);
|
||||
mutateNbt(compound -> compound.set("CustomPotionEffects", potionList));
|
||||
|
||||
return this;
|
||||
|
@ -6,16 +6,14 @@ import net.minestom.server.item.ItemMeta;
|
||||
import net.minestom.server.item.ItemMetaBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTString;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
import org.jglrxavpok.hephaistos.nbt.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WritableBookMeta extends ItemMeta implements ItemMetaBuilder.Provider<WritableBookMeta.Builder> {
|
||||
|
||||
@ -67,13 +65,12 @@ public class WritableBookMeta extends ItemMeta implements ItemMetaBuilder.Provid
|
||||
public Builder pages(@NotNull List<@NotNull Component> pages) {
|
||||
this.pages = new ArrayList<>(pages);
|
||||
|
||||
handleCollection(pages, "pages", () -> {
|
||||
NBTList<NBTString> list = new NBTList<>(NBTTypes.TAG_String);
|
||||
for (Component page : pages) {
|
||||
list.add(new NBTString(LegacyComponentSerializer.legacySection().serialize(page)));
|
||||
}
|
||||
return list;
|
||||
});
|
||||
handleCollection(pages, "pages", () -> NBT.List(
|
||||
NBTType.TAG_String,
|
||||
pages.stream()
|
||||
.map(page -> new NBTString(LegacyComponentSerializer.legacySection().serialize(page)))
|
||||
.toList()
|
||||
));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import org.jglrxavpok.hephaistos.nbt.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WrittenBookMeta extends ItemMeta implements ItemMetaBuilder.Provider<WrittenBookMeta.Builder> {
|
||||
|
||||
@ -115,13 +116,12 @@ public class WrittenBookMeta extends ItemMeta implements ItemMetaBuilder.Provide
|
||||
public Builder pages(@NotNull List<@NotNull Component> pages) {
|
||||
this.pages = new ArrayList<>(pages);
|
||||
|
||||
handleCollection(pages, "pages", () -> {
|
||||
NBTList<NBTString> list = new NBTList<>(NBTTypes.TAG_String);
|
||||
for (Component page : pages) {
|
||||
list.add(new NBTString(GsonComponentSerializer.gson().serialize(page)));
|
||||
}
|
||||
return list;
|
||||
});
|
||||
handleCollection(pages, "pages", () -> NBT.List(
|
||||
NBTType.TAG_String,
|
||||
pages.stream()
|
||||
.map(page -> new NBTString(GsonComponentSerializer.gson().serialize(page)))
|
||||
.toList()
|
||||
));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -9,6 +9,7 @@ import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.binary.Writeable;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -18,7 +19,6 @@ import java.util.Objects;
|
||||
public record ChunkData(@NotNull NBTCompound heightmaps, byte @NotNull [] data,
|
||||
@NotNull Map<Integer, Block> blockEntities) implements Writeable {
|
||||
public ChunkData {
|
||||
heightmaps = heightmaps.deepClone();
|
||||
data = data.clone();
|
||||
blockEntities = Map.copyOf(blockEntities);
|
||||
}
|
||||
@ -56,15 +56,16 @@ public record ChunkData(@NotNull NBTCompound heightmaps, byte @NotNull [] data,
|
||||
// Append handler tags
|
||||
final BlockHandler handler = block.handler();
|
||||
if (handler != null) {
|
||||
resultNbt = new NBTCompound();
|
||||
final NBTCompound blockNbt = Objects.requireNonNullElseGet(block.nbt(), NBTCompound::new);
|
||||
for (Tag<?> tag : handler.getBlockEntityTags()) {
|
||||
final var value = tag.read(blockNbt);
|
||||
if (value != null) {
|
||||
// Tag is present and valid
|
||||
tag.writeUnsafe(resultNbt, value);
|
||||
resultNbt = NBT.Compound(nbt -> {
|
||||
final NBTCompound blockNbt = Objects.requireNonNullElseGet(block.nbt(), NBTCompound::new);
|
||||
for (Tag<?> tag : handler.getBlockEntityTags()) {
|
||||
final var value = tag.read(blockNbt);
|
||||
if (value != null) {
|
||||
// Tag is present and valid
|
||||
tag.writeUnsafe(nbt, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Complete nbt shall be sent if the block has no handler
|
||||
// Necessary to support all vanilla blocks
|
||||
|
@ -3,7 +3,7 @@ package net.minestom.server.permission;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.SNBTParser;
|
||||
import org.jglrxavpok.hephaistos.parser.SNBTParser;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -1,13 +1,16 @@
|
||||
package net.minestom.server.tag;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompoundLike;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTException;
|
||||
import org.jglrxavpok.hephaistos.nbt.SNBTParser;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
import org.jglrxavpok.hephaistos.parser.SNBTParser;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.Objects;
|
||||
@ -31,16 +34,15 @@ public class Tag<T> {
|
||||
* Writing will override all tags. Proceed with caution.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public static final Tag<String> SNBT = new Tag<>(null, NBTCompound::toSNBT, (original, snbt) -> {
|
||||
public static final Tag<String> SNBT = new Tag<>(null, n -> n.toCompound().toSNBT(), (original, snbt) -> {
|
||||
try {
|
||||
final var updated = new SNBTParser(new StringReader(snbt)).parse();
|
||||
if (!(updated instanceof NBTCompound updatedCompound))
|
||||
throw new IllegalArgumentException("'" + snbt + "' is not a compound!");
|
||||
original.clear();
|
||||
updatedCompound.getKeys().forEach(s ->
|
||||
original.set(s, Objects.requireNonNull(updatedCompound.get(s))));
|
||||
updatedCompound.forEach(original::set);
|
||||
} catch (NBTException e) {
|
||||
e.printStackTrace();
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
}
|
||||
}, null);
|
||||
|
||||
@ -50,20 +52,20 @@ public class Tag<T> {
|
||||
* Writing will override all tags. Proceed with caution.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public static final Tag<NBTCompound> NBT = new Tag<>(null, NBTCompound::deepClone, (original, updated) -> {
|
||||
public static final Tag<NBTCompound> NBT = new Tag<>(null, NBTCompoundLike::toCompound, (original, updated) -> {
|
||||
original.clear();
|
||||
updated.getKeys().forEach(s -> original.set(s, Objects.requireNonNull(updated.get(s))));
|
||||
updated.forEach(original::set);
|
||||
}, null);
|
||||
|
||||
private final String key;
|
||||
private final Function<NBTCompound, T> readFunction;
|
||||
private final BiConsumer<NBTCompound, T> writeConsumer;
|
||||
private final Function<NBTCompoundLike, T> readFunction;
|
||||
private final BiConsumer<MutableNBTCompound, T> writeConsumer;
|
||||
|
||||
private final Supplier<T> defaultValue;
|
||||
|
||||
protected Tag(@Nullable String key,
|
||||
@NotNull Function<NBTCompound, T> readFunction,
|
||||
@Nullable BiConsumer<NBTCompound, T> writeConsumer,
|
||||
@NotNull Function<NBTCompoundLike, T> readFunction,
|
||||
@Nullable BiConsumer<MutableNBTCompound, T> writeConsumer,
|
||||
@Nullable Supplier<T> defaultValue) {
|
||||
this.key = key;
|
||||
this.readFunction = readFunction;
|
||||
@ -73,8 +75,8 @@ public class Tag<T> {
|
||||
}
|
||||
|
||||
protected Tag(@Nullable String key,
|
||||
@NotNull Function<NBTCompound, T> readFunction,
|
||||
@Nullable BiConsumer<NBTCompound, T> writeConsumer) {
|
||||
@NotNull Function<NBTCompoundLike, T> readFunction,
|
||||
@Nullable BiConsumer<MutableNBTCompound, T> writeConsumer) {
|
||||
this(key, readFunction, writeConsumer, null);
|
||||
}
|
||||
|
||||
@ -126,7 +128,7 @@ public class Tag<T> {
|
||||
});
|
||||
}
|
||||
|
||||
public @Nullable T read(@NotNull NBTCompound nbtCompound) {
|
||||
public @Nullable T read(@NotNull NBTCompoundLike nbtCompound) {
|
||||
T result = readFunction.apply(nbtCompound);
|
||||
if (result == null) {
|
||||
final var supplier = defaultValue;
|
||||
@ -135,15 +137,15 @@ public class Tag<T> {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void write(@NotNull NBTCompound nbtCompound, @Nullable T value) {
|
||||
public void write(@NotNull MutableNBTCompound nbtCompound, @Nullable T value) {
|
||||
if (key == null || value != null) {
|
||||
this.writeConsumer.accept(nbtCompound, value);
|
||||
} else {
|
||||
nbtCompound.removeTag(key);
|
||||
nbtCompound.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeUnsafe(@NotNull NBTCompound nbtCompound, @Nullable Object value) {
|
||||
public void writeUnsafe(@NotNull MutableNBTCompound nbtCompound, @Nullable Object value) {
|
||||
write(nbtCompound, (T) value);
|
||||
}
|
||||
|
||||
@ -185,7 +187,7 @@ public class Tag<T> {
|
||||
|
||||
public static @NotNull Tag<byte[]> ByteArray(@NotNull String key) {
|
||||
return new Tag<>(key,
|
||||
nbtCompound -> nbtCompound.getByteArray(key),
|
||||
nbtCompound -> nbtCompound.getByteArray(key).copyArray(),
|
||||
(nbtCompound, value) -> nbtCompound.setByteArray(key, value));
|
||||
}
|
||||
|
||||
@ -199,24 +201,20 @@ public class Tag<T> {
|
||||
return new Tag<>(key,
|
||||
nbt -> {
|
||||
final var currentNBT = nbt.get(key);
|
||||
// Avoid a NPE when cloning a null variable.
|
||||
if (currentNBT == null) {
|
||||
return null;
|
||||
}
|
||||
return (T) currentNBT.deepClone();
|
||||
return (T) currentNBT;
|
||||
},
|
||||
((nbt, value) -> nbt.set(key, value.deepClone())));
|
||||
((nbt, value) -> nbt.set(key, value)));
|
||||
}
|
||||
|
||||
public static @NotNull Tag<int[]> IntArray(@NotNull String key) {
|
||||
return new Tag<>(key,
|
||||
nbtCompound -> nbtCompound.getIntArray(key),
|
||||
nbtCompound -> nbtCompound.getIntArray(key).copyArray(),
|
||||
(nbtCompound, value) -> nbtCompound.setIntArray(key, value));
|
||||
}
|
||||
|
||||
public static @NotNull Tag<long[]> LongArray(@NotNull String key) {
|
||||
return new Tag<>(key,
|
||||
nbtCompound -> nbtCompound.getLongArray(key),
|
||||
nbtCompound -> nbtCompound.getLongArray(key).copyArray(),
|
||||
(nbtCompound, value) -> nbtCompound.setLongArray(key, value));
|
||||
}
|
||||
|
||||
@ -231,19 +229,15 @@ public class Tag<T> {
|
||||
public static <T> @NotNull Tag<T> Structure(@NotNull String key, @NotNull TagSerializer<T> serializer) {
|
||||
return new Tag<>(key,
|
||||
nbtCompound -> {
|
||||
final var compound = nbtCompound.getCompound(key);
|
||||
if (compound == null) {
|
||||
return null;
|
||||
}
|
||||
final NBTCompound compound = nbtCompound.getCompound(key);
|
||||
if (compound == null) return null;
|
||||
return serializer.read(TagReadable.fromCompound(compound));
|
||||
},
|
||||
(nbtCompound, value) -> {
|
||||
var compound = nbtCompound.getCompound(key);
|
||||
if (compound == null) {
|
||||
compound = new NBTCompound();
|
||||
nbtCompound.set(key, compound);
|
||||
}
|
||||
serializer.write(TagWritable.fromCompound(compound), value);
|
||||
MutableNBTCompound mutableCopy = nbtCompound.get(key) instanceof NBTCompound c ?
|
||||
c.toMutableCompound() : new MutableNBTCompound();
|
||||
serializer.write(TagWritable.fromCompound(mutableCopy), value);
|
||||
nbtCompound.set(key, mutableCopy.toCompound());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@ package net.minestom.server.tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompoundGetters;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompoundLike;
|
||||
|
||||
/**
|
||||
* Represents an element which can read {@link Tag tags}.
|
||||
@ -34,7 +36,7 @@ public interface TagReadable {
|
||||
* @param compound the compound to convert
|
||||
* @return a {@link TagReadable} capable of reading {@code compound}
|
||||
*/
|
||||
static @NotNull TagReadable fromCompound(@NotNull NBTCompound compound) {
|
||||
static @NotNull TagReadable fromCompound(@NotNull NBTCompoundLike compound) {
|
||||
return new TagReadable() {
|
||||
@Override
|
||||
public <T> @Nullable T getTag(@NotNull Tag<T> tag) {
|
||||
|
@ -3,6 +3,7 @@ package net.minestom.server.tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
|
||||
/**
|
||||
* Represents an element which can write {@link Tag tags}.
|
||||
@ -28,7 +29,7 @@ public interface TagWritable {
|
||||
* @param compound the compound to convert
|
||||
* @return a {@link TagWritable} capable of writing {@code compound}
|
||||
*/
|
||||
static @NotNull TagWritable fromCompound(@NotNull NBTCompound compound) {
|
||||
static @NotNull TagWritable fromCompound(@NotNull MutableNBTCompound compound) {
|
||||
return new TagWritable() {
|
||||
@Override
|
||||
public <T> void setTag(@NotNull Tag<T> tag, @Nullable T value) {
|
||||
|
@ -20,10 +20,12 @@ import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.*;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// for lack of a better name
|
||||
public final class NBTUtils {
|
||||
@ -79,34 +81,35 @@ public final class NBTUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveAllItems(@NotNull NBTList<NBTCompound> list, @NotNull Inventory inventory) {
|
||||
public static void saveAllItems(@NotNull List<NBTCompound> list, @NotNull Inventory inventory) {
|
||||
for (int i = 0; i < inventory.getSize(); i++) {
|
||||
final ItemStack stack = inventory.getItemStack(i);
|
||||
NBTCompound nbt = new NBTCompound();
|
||||
|
||||
NBTCompound tag = stack.getMeta().toNBT();
|
||||
|
||||
nbt.set("tag", tag);
|
||||
nbt.setByte("Slot", (byte) i);
|
||||
nbt.setByte("Count", (byte) stack.getAmount());
|
||||
nbt.setString("id", stack.getMaterial().name());
|
||||
|
||||
list.add(nbt);
|
||||
final int slotIndex = i;
|
||||
list.add(NBT.Compound(nbt -> {
|
||||
nbt.set("tag", tag);
|
||||
nbt.setByte("Slot", (byte) slotIndex);
|
||||
nbt.setByte("Count", (byte) stack.getAmount());
|
||||
nbt.setString("id", stack.getMaterial().name());
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeEnchant(@NotNull NBTCompound nbt, @NotNull String listName,
|
||||
public static void writeEnchant(@NotNull MutableNBTCompound nbt, @NotNull String listName,
|
||||
@NotNull Map<Enchantment, Short> enchantmentMap) {
|
||||
NBTList<NBTCompound> enchantList = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
for (var entry : enchantmentMap.entrySet()) {
|
||||
final Enchantment enchantment = entry.getKey();
|
||||
final short level = entry.getValue();
|
||||
enchantList.add(new NBTCompound()
|
||||
.setShort("lvl", level)
|
||||
.setString("id", enchantment.name())
|
||||
);
|
||||
}
|
||||
nbt.set(listName, enchantList);
|
||||
nbt.set(listName, NBT.List(
|
||||
NBTType.TAG_Compound,
|
||||
enchantmentMap.entrySet().stream()
|
||||
.map(entry ->
|
||||
NBT.Compound(n -> {
|
||||
n.setShort("lvl", entry.getValue());
|
||||
n.setString("id", entry.getKey().name());
|
||||
})
|
||||
)
|
||||
.toList()
|
||||
));
|
||||
}
|
||||
|
||||
public static @NotNull ItemStack readItemStack(@NotNull BinaryReader reader) {
|
||||
@ -134,7 +137,7 @@ public final class NBTUtils {
|
||||
if (nbt.containsKey("display")) {
|
||||
final NBTCompound display = nbt.getCompound("display");
|
||||
if (display.containsKey("Name")) {
|
||||
final String rawName = StringUtils.unescapeJavaString(display.getString("Name"));
|
||||
final String rawName = display.getString("Name");
|
||||
final Component displayName = GsonComponentSerializer.gson().deserialize(rawName);
|
||||
metaBuilder.displayName(displayName);
|
||||
}
|
||||
@ -142,7 +145,7 @@ public final class NBTUtils {
|
||||
NBTList<NBTString> loreList = display.getList("Lore");
|
||||
List<Component> lore = new ArrayList<>();
|
||||
for (NBTString s : loreList) {
|
||||
final String rawLore = StringUtils.unescapeJavaString(s.getValue());
|
||||
final String rawLore = s.getValue();
|
||||
lore.add(GsonComponentSerializer.gson().deserialize(rawLore));
|
||||
}
|
||||
metaBuilder.lore(lore);
|
||||
@ -161,7 +164,7 @@ public final class NBTUtils {
|
||||
for (NBTCompound attributeNBT : nbtAttributes) {
|
||||
final UUID uuid;
|
||||
{
|
||||
final int[] uuidArray = attributeNBT.getIntArray("UUID");
|
||||
final int[] uuidArray = attributeNBT.getIntArray("UUID").copyArray();
|
||||
uuid = Utils.intArrayToUuid(uuidArray);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ public final class SerializerUtils {
|
||||
|
||||
public static Point longToBlockPosition(long value) {
|
||||
final int x = (int) (value >> 38);
|
||||
final int y = (int) (value & 0xFFF);
|
||||
final int y = (int) (value << 52 >> 52);
|
||||
final int z = (int) (value << 26 >> 38);
|
||||
return new Vec(x, y, z);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import net.minestom.server.utils.SerializerUtils;
|
||||
import net.minestom.server.utils.Utils;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.CompressedProcesser;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTException;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTReader;
|
||||
@ -32,7 +33,7 @@ import java.util.function.Supplier;
|
||||
*/
|
||||
public class BinaryReader extends InputStream {
|
||||
private final ByteBuffer buffer;
|
||||
private NBTReader nbtReader;
|
||||
private NBTReader nbtReader = null;
|
||||
|
||||
public BinaryReader(@NotNull ByteBuffer buffer) {
|
||||
this.buffer = buffer;
|
||||
@ -257,7 +258,7 @@ public class BinaryReader extends InputStream {
|
||||
public NBT readTag() {
|
||||
NBTReader reader = this.nbtReader;
|
||||
if (reader == null) {
|
||||
reader = new NBTReader(this, false);
|
||||
reader = new NBTReader(this, CompressedProcesser.NONE);
|
||||
this.nbtReader = reader;
|
||||
}
|
||||
try {
|
||||
|
@ -9,6 +9,7 @@ import net.minestom.server.utils.SerializerUtils;
|
||||
import net.minestom.server.utils.Utils;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.CompressedProcesser;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTWriter;
|
||||
|
||||
@ -303,7 +304,7 @@ public class BinaryWriter extends OutputStream {
|
||||
|
||||
public void writeNBT(@NotNull String name, @NotNull NBT tag) {
|
||||
if (nbtWriter == null) {
|
||||
this.nbtWriter = new NBTWriter(this, false);
|
||||
this.nbtWriter = new NBTWriter(this, CompressedProcesser.NONE);
|
||||
}
|
||||
try {
|
||||
nbtWriter.writeNamed(name, tag);
|
||||
|
@ -3,8 +3,10 @@ package net.minestom.server.world;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@ -26,8 +28,9 @@ public class DimensionType {
|
||||
.ceilingEnabled(false)
|
||||
.fixedTime(null)
|
||||
.ambientLight(0.0f)
|
||||
.height(256)
|
||||
.logicalHeight(256)
|
||||
.height(384)
|
||||
.minY(-64)
|
||||
.logicalHeight(384)
|
||||
.infiniburn(NamespaceID.from("minecraft:infiniburn_overworld"))
|
||||
.build();
|
||||
|
||||
@ -107,35 +110,33 @@ public class DimensionType {
|
||||
|
||||
@NotNull
|
||||
public NBTCompound toIndexedNBT() {
|
||||
NBTCompound nbt = new NBTCompound();
|
||||
NBTCompound element = toNBT();
|
||||
nbt.setString("name", name.toString());
|
||||
nbt.setInt("id", id);
|
||||
nbt.set("element", element);
|
||||
return nbt;
|
||||
return NBT.Compound(Map.of(
|
||||
"name", NBT.String(name.toString()),
|
||||
"id", NBT.Int(id),
|
||||
"element", toNBT()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public NBTCompound toNBT() {
|
||||
NBTCompound nbt = new NBTCompound()
|
||||
.setFloat("ambient_light", ambientLight)
|
||||
.setString("infiniburn", infiniburn.toString())
|
||||
.setByte("natural", (byte) (natural ? 0x01 : 0x00))
|
||||
.setByte("has_ceiling", (byte) (ceilingEnabled ? 0x01 : 0x00))
|
||||
.setByte("has_skylight", (byte) (skylightEnabled ? 0x01 : 0x00))
|
||||
.setByte("ultrawarm", (byte) (ultrawarm ? 0x01 : 0x00))
|
||||
.setByte("has_raids", (byte) (raidCapable ? 0x01 : 0x00))
|
||||
.setByte("respawn_anchor_works", (byte) (respawnAnchorSafe ? 0x01 : 0x00))
|
||||
.setByte("bed_works", (byte) (bedSafe ? 0x01 : 0x00))
|
||||
.setString("effects", effects)
|
||||
.setByte("piglin_safe", (byte) (piglinSafe ? 0x01 : 0x00))
|
||||
.setInt("min_y", minY)
|
||||
.setInt("height", height)
|
||||
.setInt("logical_height", logicalHeight)
|
||||
.setInt("coordinate_scale", coordinateScale)
|
||||
.setString("name", name.toString());
|
||||
if (fixedTime != null) nbt.setLong("fixed_time", fixedTime);
|
||||
return nbt;
|
||||
return NBT.Compound(nbt -> {
|
||||
nbt.setFloat("ambient_light", ambientLight);
|
||||
nbt.setString("infiniburn", infiniburn.toString());
|
||||
nbt.setByte("natural", (byte) (natural ? 0x01 : 0x00));
|
||||
nbt.setByte("has_ceiling", (byte) (ceilingEnabled ? 0x01 : 0x00));
|
||||
nbt.setByte("has_skylight", (byte) (skylightEnabled ? 0x01 : 0x00));
|
||||
nbt.setByte("ultrawarm", (byte) (ultrawarm ? 0x01 : 0x00));
|
||||
nbt.setByte("has_raids", (byte) (raidCapable ? 0x01 : 0x00));
|
||||
nbt.setByte("respawn_anchor_works", (byte) (respawnAnchorSafe ? 0x01 : 0x00));
|
||||
nbt.setByte("bed_works", (byte) (bedSafe ? 0x01 : 0x00));
|
||||
nbt.setString("effects", effects);
|
||||
nbt.setByte("piglin_safe", (byte) (piglinSafe ? 0x01 : 0x00));
|
||||
nbt.setInt("min_y", minY);
|
||||
nbt.setInt("height", height);
|
||||
nbt.setInt("logical_height", logicalHeight);
|
||||
nbt.setInt("coordinate_scale", coordinateScale);
|
||||
nbt.setString("name", name.toString());
|
||||
if (fixedTime != null) nbt.setLong("fixed_time", fixedTime);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,13 +3,15 @@ package net.minestom.server.world;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Allows servers to register custom dimensions. Also used during player login to send the list of all existing dimensions.
|
||||
@ -88,13 +90,14 @@ public final class DimensionTypeManager {
|
||||
* @return an nbt compound containing the registered dimensions
|
||||
*/
|
||||
public @NotNull NBTCompound toNBT() {
|
||||
NBTCompound dimensions = new NBTCompound();
|
||||
dimensions.setString("type", "minecraft:dimension_type");
|
||||
NBTList<NBTCompound> dimensionList = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
for (DimensionType dimensionType : dimensionTypes) {
|
||||
dimensionList.add(dimensionType.toIndexedNBT());
|
||||
}
|
||||
dimensions.set("value", dimensionList);
|
||||
return dimensions;
|
||||
return NBT.Compound(dimensions -> {
|
||||
dimensions.setString("type", "minecraft:dimension_type");
|
||||
dimensions.set("value", NBT.List(
|
||||
NBTType.TAG_Compound,
|
||||
dimensionTypes.stream()
|
||||
.map(DimensionType::toIndexedNBT)
|
||||
.toList()
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.Locale;
|
||||
@ -61,22 +62,22 @@ public final class Biome {
|
||||
Check.notNull(name, "The biome namespace cannot be null");
|
||||
Check.notNull(effects, "The biome effects cannot be null");
|
||||
|
||||
NBTCompound nbt = new NBTCompound();
|
||||
nbt.setString("name", name.toString());
|
||||
nbt.setInt("id", id());
|
||||
return NBT.Compound(nbt -> {
|
||||
nbt.setString("name", name.toString());
|
||||
nbt.setInt("id", id());
|
||||
|
||||
NBTCompound element = new NBTCompound();
|
||||
element.setFloat("depth", depth);
|
||||
element.setFloat("temperature", temperature);
|
||||
element.setFloat("scale", scale);
|
||||
element.setFloat("downfall", downfall);
|
||||
element.setString("category", category.name().toLowerCase(Locale.ROOT));
|
||||
element.setString("precipitation", precipitation.name().toLowerCase(Locale.ROOT));
|
||||
if (temperatureModifier != TemperatureModifier.NONE)
|
||||
element.setString("temperature_modifier", temperatureModifier.name().toLowerCase(Locale.ROOT));
|
||||
element.set("effects", effects.toNbt());
|
||||
nbt.set("element", element);
|
||||
return nbt;
|
||||
nbt.set("element", NBT.Compound(element -> {
|
||||
element.setFloat("depth", depth);
|
||||
element.setFloat("temperature", temperature);
|
||||
element.setFloat("scale", scale);
|
||||
element.setFloat("downfall", downfall);
|
||||
element.setString("category", category.name().toLowerCase(Locale.ROOT));
|
||||
element.setString("precipitation", precipitation.name().toLowerCase(Locale.ROOT));
|
||||
if (temperatureModifier != TemperatureModifier.NONE)
|
||||
element.setString("temperature_modifier", temperatureModifier.name().toLowerCase(Locale.ROOT));
|
||||
element.set("effects", effects.toNbt());
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
public int id() {
|
||||
|
@ -2,9 +2,11 @@ package net.minestom.server.world.biomes;
|
||||
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public record BiomeEffects(int fogColor, int skyColor, int waterColor, int waterFogColor, int foliageColor,
|
||||
int grassColor,
|
||||
@ -17,26 +19,28 @@ public record BiomeEffects(int fogColor, int skyColor, int waterColor, int water
|
||||
}
|
||||
|
||||
public NBTCompound toNbt() {
|
||||
NBTCompound nbt = new NBTCompound();
|
||||
nbt.setInt("fog_color", fogColor);
|
||||
if (foliageColor != -1) nbt.setInt("foliage_color", foliageColor);
|
||||
if (grassColor != -1) nbt.setInt("grass_color", grassColor);
|
||||
nbt.setInt("sky_color", skyColor);
|
||||
nbt.setInt("water_color", waterColor);
|
||||
nbt.setInt("water_fog_color", waterFogColor);
|
||||
if (grassColorModifier != null)
|
||||
nbt.setString("grass_color_modifier", grassColorModifier.name().toLowerCase(Locale.ROOT));
|
||||
if (biomeParticle != null)
|
||||
nbt.set("particle", biomeParticle.toNbt());
|
||||
if (ambientSound != null)
|
||||
nbt.setString("ambient_sound", ambientSound.toString());
|
||||
if (moodSound != null)
|
||||
nbt.set("mood_sound", moodSound.toNbt());
|
||||
if (additionsSound != null)
|
||||
nbt.set("additions_sound", additionsSound.toNbt());
|
||||
if (music != null)
|
||||
nbt.set("music", music.toNbt());
|
||||
return nbt;
|
||||
return NBT.Compound(nbt -> {
|
||||
nbt.setInt("fog_color", fogColor);
|
||||
if (foliageColor != -1)
|
||||
nbt.setInt("foliage_color", foliageColor);
|
||||
if (grassColor != -1)
|
||||
nbt.setInt("grass_color", grassColor);
|
||||
nbt.setInt("sky_color", skyColor);
|
||||
nbt.setInt("water_color", waterColor);
|
||||
nbt.setInt("water_fog_color", waterFogColor);
|
||||
if (grassColorModifier != null)
|
||||
nbt.setString("grass_color_modifier", grassColorModifier.name().toLowerCase(Locale.ROOT));
|
||||
if (biomeParticle != null)
|
||||
nbt.set("particle", biomeParticle.toNbt());
|
||||
if (ambientSound != null)
|
||||
nbt.setString("ambient_sound", ambientSound.toString());
|
||||
if (moodSound != null)
|
||||
nbt.set("mood_sound", moodSound.toNbt());
|
||||
if (additionsSound != null)
|
||||
nbt.set("additions_sound", additionsSound.toNbt());
|
||||
if (music != null)
|
||||
nbt.set("music", music.toNbt());
|
||||
});
|
||||
}
|
||||
|
||||
public enum GrassColorModifier {
|
||||
@ -45,32 +49,29 @@ public record BiomeEffects(int fogColor, int skyColor, int waterColor, int water
|
||||
|
||||
public record MoodSound(NamespaceID sound, int tickDelay, int blockSearchExtent, double offset) {
|
||||
public @NotNull NBTCompound toNbt() {
|
||||
NBTCompound nbt = new NBTCompound();
|
||||
nbt.setString("sound", sound.toString());
|
||||
nbt.setInt("tick_delay", tickDelay);
|
||||
nbt.setInt("block_search_extent", blockSearchExtent);
|
||||
nbt.setDouble("offset", offset);
|
||||
return nbt;
|
||||
return NBT.Compound(Map.of(
|
||||
"sound", NBT.String(sound.toString()),
|
||||
"tick_delay", NBT.Int(tickDelay),
|
||||
"block_search_extent", NBT.Int(blockSearchExtent),
|
||||
"offset", NBT.Double(offset)));
|
||||
}
|
||||
}
|
||||
|
||||
public record AdditionsSound(NamespaceID sound, double tickChance) {
|
||||
public @NotNull NBTCompound toNbt() {
|
||||
NBTCompound nbt = new NBTCompound();
|
||||
nbt.setString("sound", sound.toString());
|
||||
nbt.setDouble("tick_chance", tickChance);
|
||||
return nbt;
|
||||
return NBT.Compound(Map.of(
|
||||
"sound", NBT.String(sound.toString()),
|
||||
"tick_chance", NBT.Double(tickChance)));
|
||||
}
|
||||
}
|
||||
|
||||
public record Music(NamespaceID sound, int minDelay, int maxDelay, boolean replaceCurrentMusic) {
|
||||
public @NotNull NBTCompound toNbt() {
|
||||
NBTCompound nbt = new NBTCompound();
|
||||
nbt.setString("sound", sound.toString());
|
||||
nbt.setInt("min_delay", minDelay);
|
||||
nbt.setInt("max_delay", maxDelay);
|
||||
nbt.setByte("replace_current_music", replaceCurrentMusic ? (byte) 1 : (byte) 0);
|
||||
return nbt;
|
||||
return NBT.Compound(Map.of(
|
||||
"sound", NBT.String(sound.toString()),
|
||||
"min_delay", NBT.Int(minDelay),
|
||||
"max_delay", NBT.Int(maxDelay),
|
||||
"replace_current_music", NBT.Boolean(replaceCurrentMusic)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,14 @@ package net.minestom.server.world.biomes;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Allows servers to register custom dimensions. Also used during player joining to send the list of all existing dimensions.
|
||||
@ -71,13 +73,8 @@ public final class BiomeManager {
|
||||
}
|
||||
|
||||
public synchronized NBTCompound toNBT() {
|
||||
NBTCompound biomes = new NBTCompound();
|
||||
biomes.setString("type", "minecraft:worldgen/biome");
|
||||
NBTList<NBTCompound> biomesList = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
for (Biome biome : this.biomes.values()) {
|
||||
biomesList.add(biome.toNbt());
|
||||
}
|
||||
biomes.set("value", biomesList);
|
||||
return biomes;
|
||||
return NBT.Compound(Map.of(
|
||||
"type", NBT.String("minecraft:worldgen/biome"),
|
||||
"value", NBT.List(NBTType.TAG_Compound, biomes.values().stream().map(Biome::toNbt).toList())));
|
||||
}
|
||||
}
|
||||
|
@ -3,16 +3,16 @@ package net.minestom.server.world.biomes;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public record BiomeParticle(float probability, Option option) {
|
||||
public NBTCompound toNbt() {
|
||||
NBTCompound nbt = new NBTCompound();
|
||||
nbt.setFloat("probability", probability);
|
||||
nbt.set("options", option.toNbt());
|
||||
return nbt;
|
||||
return NBT.Compound(Map.of(
|
||||
"probability", NBT.Float(probability),
|
||||
"options", option.toNbt()));
|
||||
}
|
||||
|
||||
public interface Option {
|
||||
@ -25,16 +25,16 @@ public record BiomeParticle(float probability, Option option) {
|
||||
|
||||
@Override
|
||||
public NBTCompound toNbt() {
|
||||
NBTCompound nbtCompound = new NBTCompound();
|
||||
nbtCompound.setString("type", type);
|
||||
nbtCompound.setString("Name", block.name());
|
||||
Map<String, String> propertiesMap = block.properties();
|
||||
if (propertiesMap.size() != 0) {
|
||||
NBTCompound properties = new NBTCompound();
|
||||
propertiesMap.forEach(properties::setString);
|
||||
nbtCompound.set("Properties", properties);
|
||||
}
|
||||
return nbtCompound;
|
||||
return NBT.Compound(nbtCompound -> {
|
||||
nbtCompound.setString("type", type);
|
||||
nbtCompound.setString("Name", block.name());
|
||||
Map<String, String> propertiesMap = block.properties();
|
||||
if (propertiesMap.size() != 0) {
|
||||
nbtCompound.set("Properties", NBT.Compound(p -> {
|
||||
propertiesMap.forEach(p::setString);
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,13 +43,12 @@ public record BiomeParticle(float probability, Option option) {
|
||||
|
||||
@Override
|
||||
public NBTCompound toNbt() {
|
||||
NBTCompound nbtCompound = new NBTCompound();
|
||||
nbtCompound.setString("type", type);
|
||||
nbtCompound.setFloat("r", red);
|
||||
nbtCompound.setFloat("g", green);
|
||||
nbtCompound.setFloat("b", blue);
|
||||
nbtCompound.setFloat("scale", scale);
|
||||
return nbtCompound;
|
||||
return NBT.Compound(Map.of(
|
||||
"type", NBT.String(type),
|
||||
"r", NBT.Float(red),
|
||||
"g", NBT.Float(green),
|
||||
"b", NBT.Float(blue),
|
||||
"scale", NBT.Float(scale)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,17 +59,16 @@ public record BiomeParticle(float probability, Option option) {
|
||||
public NBTCompound toNbt() {
|
||||
//todo test count might be wrong type
|
||||
NBTCompound nbtCompound = item.getMeta().toNBT();
|
||||
nbtCompound.setString("type", type);
|
||||
return nbtCompound;
|
||||
return nbtCompound.modify(n -> {
|
||||
n.setString("type", type);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public record NormalOption(NamespaceID type) implements Option {
|
||||
@Override
|
||||
public NBTCompound toNbt() {
|
||||
NBTCompound nbtCompound = new NBTCompound();
|
||||
nbtCompound.setString("type", type.toString());
|
||||
return nbtCompound;
|
||||
return NBT.Compound(Map.of("type", NBT.String(type.toString())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,13 +10,15 @@ import net.minestom.server.tag.TagWritable;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CampfireHandler implements BlockHandler {
|
||||
|
||||
@ -44,15 +46,16 @@ public class CampfireHandler implements BlockHandler {
|
||||
writer.removeTag(internal);
|
||||
return;
|
||||
}
|
||||
NBTList<NBTCompound> items = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
for (var item : value) {
|
||||
NBTCompound compound = new NBTCompound()
|
||||
.setByte("Count", (byte) item.getAmount())
|
||||
.setByte("Slot", (byte) 1)
|
||||
.setString("id", item.getMaterial().name());
|
||||
items.add(compound);
|
||||
}
|
||||
writer.setTag(internal, items);
|
||||
writer.setTag(internal, NBT.List(
|
||||
NBTType.TAG_Compound,
|
||||
value.stream()
|
||||
.map(item -> NBT.Compound(nbt -> {
|
||||
nbt.setByte("Count", (byte) item.getAmount());
|
||||
nbt.setByte("Slot", (byte) 1);
|
||||
nbt.setString("id", item.getMaterial().name());
|
||||
}))
|
||||
.toList()
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -3,6 +3,7 @@ package permissions;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.permission.Permission;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@ -36,9 +37,11 @@ public class TestPermissions {
|
||||
};
|
||||
|
||||
permission1 = new Permission("perm.name",
|
||||
new NBTCompound()
|
||||
.setString("name", "Minestom")
|
||||
.setInt("amount", 5));
|
||||
NBT.Compound(nbt -> {
|
||||
nbt.setString("name", "Minestom");
|
||||
nbt.setInt("amount", 5);
|
||||
})
|
||||
);
|
||||
|
||||
permission2 = new Permission("perm.name2");
|
||||
}
|
||||
|
95
src/test/java/regressions/ItemMetaBuilderRegressions.java
Normal file
95
src/test/java/regressions/ItemMetaBuilderRegressions.java
Normal file
@ -0,0 +1,95 @@
|
||||
package regressions;
|
||||
|
||||
import net.minestom.server.item.ItemMeta;
|
||||
import net.minestom.server.item.ItemMetaBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTShort;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTString;
|
||||
import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ItemMetaBuilderRegressions {
|
||||
|
||||
private static class BasicMetaBuilder extends ItemMetaBuilder {
|
||||
@Override
|
||||
public @NotNull ItemMeta build() {
|
||||
return new ItemMeta(this) {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(@NotNull NBTCompound nbtCompound) {
|
||||
// don't care
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull Supplier<@NotNull ItemMetaBuilder> getSupplier() {
|
||||
// don't care
|
||||
return () -> this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCompound(@NotNull String key, @NotNull Consumer<@NotNull MutableNBTCompound> consumer) {
|
||||
super.handleCompound(key, consumer);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleCompoundShouldUsePreviousValue() {
|
||||
BasicMetaBuilder builder = new BasicMetaBuilder();
|
||||
|
||||
builder.handleCompound("test", nbt -> {
|
||||
nbt.setString("my_key", "AAA");
|
||||
});
|
||||
|
||||
NBTCompound nbt = builder.build().toNBT().getCompound("test");
|
||||
|
||||
assertTrue(nbt.contains("my_key"));
|
||||
assertEquals(1, nbt.getSize());
|
||||
assertTrue(nbt.get("my_key") instanceof NBTString);
|
||||
assertEquals("AAA", nbt.getString("my_key"));
|
||||
|
||||
builder.handleCompound("test", n -> {
|
||||
n.setString("my_other_key", "BBB");
|
||||
});
|
||||
|
||||
nbt = builder.build().toNBT().getCompound("test");
|
||||
|
||||
assertTrue(nbt.contains("my_key"));
|
||||
assertTrue(nbt.contains("my_other_key"));
|
||||
assertEquals(2, nbt.getSize());
|
||||
assertTrue(nbt.get("my_key") instanceof NBTString);
|
||||
assertTrue(nbt.get("my_other_key") instanceof NBTString);
|
||||
assertEquals("AAA", nbt.getString("my_key"));
|
||||
assertEquals("BBB", nbt.getString("my_other_key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearingShouldRemoveData() {
|
||||
BasicMetaBuilder builder = new BasicMetaBuilder();
|
||||
|
||||
builder.handleCompound("test", nbt -> {
|
||||
nbt.setString("my_key", "AAA");
|
||||
});
|
||||
|
||||
NBTCompound nbt = builder.build().toNBT().getCompound("test");
|
||||
assertTrue(nbt.contains("my_key"));
|
||||
assertEquals(1, nbt.getSize());
|
||||
assertTrue(nbt.get("my_key") instanceof NBTString);
|
||||
assertEquals("AAA", nbt.getString("my_key"));
|
||||
|
||||
builder.handleCompound("test", n -> {
|
||||
n.clear();
|
||||
});
|
||||
|
||||
NBTCompound rootNBT = builder.build().toNBT();
|
||||
|
||||
assertFalse(rootNBT.contains("test"));
|
||||
assertEquals(0, rootNBT.getSize());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user