mirror of
https://github.com/Minestom/Minestom.git
synced 2024-09-28 22:47:41 +02:00
Add extractClientNbt utils
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
d3fa4c810f
commit
be1495a385
@ -2,19 +2,16 @@ package net.minestom.server.network.packet.server.play.data;
|
||||
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.tag.Tag;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.binary.Writeable;
|
||||
import net.minestom.server.utils.block.BlockUtils;
|
||||
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;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public record ChunkData(@NotNull NBTCompound heightmaps, byte @NotNull [] data,
|
||||
@ -47,33 +44,13 @@ public record ChunkData(@NotNull NBTCompound heightmaps, byte @NotNull [] data,
|
||||
final var registry = block.registry();
|
||||
|
||||
final Point point = ChunkUtils.getBlockPosition(index, 0, 0);
|
||||
|
||||
writer.writeByte((byte) ((point.blockX() & 15) << 4 | point.blockZ() & 15)); // xz
|
||||
writer.writeShort((short) point.blockY()); // y
|
||||
|
||||
writer.writeVarInt(registry.blockEntityId());
|
||||
|
||||
NBTCompound resultNbt;
|
||||
// Append handler tags
|
||||
final BlockHandler handler = block.handler();
|
||||
if (handler != null) {
|
||||
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
|
||||
final NBTCompound blockNbt = block.nbt();
|
||||
resultNbt = blockNbt == null ? new NBTCompound() : blockNbt;
|
||||
}
|
||||
writer.writeNBT("", resultNbt); // block nbt
|
||||
final NBTCompound nbt = BlockUtils.extractClientNbt(block);
|
||||
assert nbt != null;
|
||||
writer.writeNBT("", nbt); // block nbt
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,17 @@ package net.minestom.server.utils.block;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.tag.Tag;
|
||||
import net.minestom.server.utils.ArrayUtils;
|
||||
import net.minestom.server.utils.StringUtils;
|
||||
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;
|
||||
|
||||
public class BlockUtils {
|
||||
|
||||
@ -83,4 +90,26 @@ public class BlockUtils {
|
||||
}
|
||||
return ArrayUtils.toMap(keys, values, entryCount);
|
||||
}
|
||||
|
||||
public static @Nullable NBTCompound extractClientNbt(@NotNull Block block) {
|
||||
if (!block.registry().isBlockEntity()) return null;
|
||||
// Append handler tags
|
||||
final BlockHandler handler = block.handler();
|
||||
final NBTCompound blockNbt = Objects.requireNonNullElseGet(block.nbt(), NBTCompound::new);
|
||||
if (handler != null) {
|
||||
// Extract explicitly defined tags and keep the rest server-side
|
||||
return NBT.Compound(nbt -> {
|
||||
for (Tag<?> tag : handler.getBlockEntityTags()) {
|
||||
final var value = tag.read(blockNbt);
|
||||
if (value != null) {
|
||||
// Tag is present and valid
|
||||
tag.writeUnsafe(nbt, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// Complete nbt shall be sent if the block has no handler
|
||||
// Necessary to support all vanilla blocks
|
||||
return blockNbt;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
package net.minestom.server.instance;
|
||||
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.tag.Tag;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import net.minestom.server.utils.block.BlockUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
public class BlockClientNbtTest {
|
||||
|
||||
@Test
|
||||
public void basic() {
|
||||
assertNull(BlockUtils.extractClientNbt(Block.STONE));
|
||||
assertNull(BlockUtils.extractClientNbt(Block.GRASS));
|
||||
assertEquals(NBTCompound.EMPTY, BlockUtils.extractClientNbt(Block.CHEST));
|
||||
|
||||
var nbt = NBT.Compound(Map.of("test", NBT.String("test")));
|
||||
assertEquals(nbt, BlockUtils.extractClientNbt(Block.CHEST.withNbt(nbt)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handler() {
|
||||
var handler = new BlockHandler() {
|
||||
@Override
|
||||
public @NotNull Collection<Tag<?>> getBlockEntityTags() {
|
||||
return List.of(Tag.String("test"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull NamespaceID getNamespaceId() {
|
||||
return NamespaceID.from("minestom:test");
|
||||
}
|
||||
};
|
||||
|
||||
var nbt = NBT.Compound(Map.of("test", NBT.String("test")));
|
||||
assertNull(BlockUtils.extractClientNbt(Block.STONE.withNbt(nbt).withHandler(handler)));
|
||||
assertEquals(nbt, BlockUtils.extractClientNbt(Block.CHEST.withNbt(nbt).withHandler(handler)));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user