From e0d54f5958e61b6a20958302985ff92bf5945386 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sat, 29 May 2021 00:07:22 +0200 Subject: [PATCH] Store handler & nbt inside DynamicChunk --- .../server/instance/DynamicChunk.java | 87 ++++++------------- .../packet/server/play/ChunkDataPacket.java | 56 ++++++------ 2 files changed, 52 insertions(+), 91 deletions(-) diff --git a/src/main/java/net/minestom/server/instance/DynamicChunk.java b/src/main/java/net/minestom/server/instance/DynamicChunk.java index 6fd59ae47..c1f43533b 100644 --- a/src/main/java/net/minestom/server/instance/DynamicChunk.java +++ b/src/main/java/net/minestom/server/instance/DynamicChunk.java @@ -13,6 +13,7 @@ import net.minestom.server.data.SerializableData; import net.minestom.server.data.SerializableDataImpl; import net.minestom.server.entity.pathfinding.PFBlockDescription; import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockHandler; import net.minestom.server.instance.palette.PaletteStorage; import net.minestom.server.network.packet.server.play.ChunkDataPacket; import net.minestom.server.utils.binary.BinaryReader; @@ -24,6 +25,7 @@ import net.minestom.server.utils.validate.Check; import net.minestom.server.world.biomes.Biome; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; import java.lang.ref.SoftReference; import java.util.Set; @@ -43,44 +45,37 @@ public class DynamicChunk extends Chunk { // WARNING: not thread-safe and should not be changed protected PaletteStorage blockPalette; - protected PaletteStorage customBlockPalette; - // Used to get all blocks with data (no null) - // Key is still chunk coordinates (see #getBlockIndex) - protected final Int2ObjectOpenHashMap blocksData = new Int2ObjectOpenHashMap<>(); + // Key = ChunkUtils#getBlockIndex + protected final Int2ObjectOpenHashMap handlerMap = new Int2ObjectOpenHashMap<>(); + protected final Int2ObjectOpenHashMap nbtMap = new Int2ObjectOpenHashMap<>(); // Contains CustomBlocks' block index which are updatable protected final IntOpenHashSet updatableBlocks = new IntOpenHashSet(); // (block index)/(last update in ms) protected final Int2LongMap updatableBlocksLastUpdate = new Int2LongOpenHashMap(); - // Block entities - protected final IntOpenHashSet blockEntities = new IntOpenHashSet(); - private long lastChangeTime; private SoftReference cachedPacket = new SoftReference<>(null); private long cachedPacketTime; public DynamicChunk(@NotNull Instance instance, @Nullable Biome[] biomes, int chunkX, int chunkZ, - @NotNull PaletteStorage blockPalette, @NotNull PaletteStorage customBlockPalette) { + @NotNull PaletteStorage blockPalette) { super(instance, biomes, chunkX, chunkZ, true); this.blockPalette = blockPalette; - this.customBlockPalette = customBlockPalette; } public DynamicChunk(@NotNull Instance instance, @Nullable Biome[] biomes, int chunkX, int chunkZ) { - this(instance, biomes, chunkX, chunkZ, - new PaletteStorage(8, 2), - new PaletteStorage(8, 2)); + this(instance, biomes, chunkX, chunkZ, new PaletteStorage(8, 2)); } @Override public void UNSAFE_setBlock(int x, int y, int z, @NotNull Block block) { final short blockStateId = block.getStateId(); - final short customBlockId = 0; // TODO + final BlockHandler handler = block.getHandler(); + final NBTCompound nbt = null; // TODO final boolean updatable = false; // TODO - final boolean nbt = false; // TODO { // Update pathfinder if (columnarSpace != null) { @@ -91,45 +86,19 @@ public class DynamicChunk extends Chunk { } final int index = getBlockIndex(x, y, z); - // True if the block is not complete air without any custom block capabilities - final boolean hasBlock = blockStateId != 0 || customBlockId != 0; - + // Block palette setBlockAt(blockPalette, x, y, z, blockStateId); - setBlockAt(customBlockPalette, x, y, z, customBlockId); - - if (!hasBlock) { - // Block has been deleted, clear cache and return - - this.blocksData.remove(index); - - this.updatableBlocks.remove(index); - this.updatableBlocksLastUpdate.remove(index); - - this.blockEntities.remove(index); - return; - } - - // Set the new data (or remove from the map if is null) - if (data != null) { - this.blocksData.put(index, data); + // Handler + if (handler != null) { + this.handlerMap.put(index, handler); } else { - this.blocksData.remove(index); + this.handlerMap.remove(index); } - - // Set update consumer - if (updatable) { - this.updatableBlocks.add(index); - this.updatableBlocksLastUpdate.put(index, System.currentTimeMillis()); + // Nbt + if (nbt != null) { + this.nbtMap.put(index, nbt); } else { - this.updatableBlocks.remove(index); - this.updatableBlocksLastUpdate.remove(index); - } - - // Set block entity - if (nbt) { - this.blockEntities.add(index); - } else { - this.blockEntities.remove(index); + this.nbtMap.remove(index); } } @@ -149,7 +118,7 @@ public class DynamicChunk extends Chunk { @NotNull @Override public Set getBlockEntities() { - return blockEntities; + return nbtMap.keySet(); } @Override @@ -205,7 +174,7 @@ public class DynamicChunk extends Chunk { final int index = getBlockIndex(x, y, z); final short blockStateId = getBlockAt(blockPalette, x, y, z); - final short customBlockId = getBlockAt(customBlockPalette, x, y, z); + final short customBlockId = 0;//getBlockAt(customBlockPalette, x, y, z); // No block at the position if (blockStateId == 0 && customBlockId == 0) @@ -350,9 +319,8 @@ public class DynamicChunk extends Chunk { packet.chunkX = chunkX; packet.chunkZ = chunkZ; packet.paletteStorage = blockPalette.clone(); - packet.customBlockPaletteStorage = customBlockPalette.clone(); - packet.blockEntities = blockEntities.clone(); - packet.blocksData = blocksData.clone(); + packet.handlerMap = handlerMap.clone(); + packet.nbtMap = nbtMap.clone(); this.cachedPacketTime = getLastChangeTime(); this.cachedPacket = new SoftReference<>(packet); @@ -364,11 +332,10 @@ public class DynamicChunk extends Chunk { public Chunk copy(@NotNull Instance instance, int chunkX, int chunkZ) { DynamicChunk dynamicChunk = new DynamicChunk(instance, biomes.clone(), chunkX, chunkZ); dynamicChunk.blockPalette = blockPalette.clone(); - dynamicChunk.customBlockPalette = customBlockPalette.clone(); - dynamicChunk.blocksData.putAll(blocksData); + dynamicChunk.handlerMap.putAll(handlerMap); dynamicChunk.updatableBlocks.addAll(updatableBlocks); dynamicChunk.updatableBlocksLastUpdate.putAll(updatableBlocksLastUpdate); - dynamicChunk.blockEntities.addAll(blockEntities); + dynamicChunk.nbtMap.putAll(nbtMap); return dynamicChunk; } @@ -376,12 +343,10 @@ public class DynamicChunk extends Chunk { @Override public void reset() { this.blockPalette.clear(); - this.customBlockPalette.clear(); - - this.blocksData.clear(); + this.handlerMap.clear(); + this.nbtMap.clear(); this.updatableBlocks.clear(); this.updatableBlocksLastUpdate.clear(); - this.blockEntities.clear(); } private short getBlockAt(@NotNull PaletteStorage paletteStorage, int x, int y, int z) { diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java index fdc745141..83a8b40dd 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java @@ -3,10 +3,9 @@ package net.minestom.server.network.packet.server.play; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.minestom.server.MinecraftServer; -import net.minestom.server.data.Data; +import net.minestom.server.instance.block.BlockHandler; import net.minestom.server.instance.block.BlockManager; import net.minestom.server.instance.palette.PaletteStorage; import net.minestom.server.instance.palette.Section; @@ -26,6 +25,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.jglrxavpok.hephaistos.nbt.NBTException; import java.io.IOException; +import java.util.Objects; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -39,10 +39,8 @@ public class ChunkDataPacket implements ServerPacket, CacheablePacket { public int chunkX, chunkZ; public PaletteStorage paletteStorage; - public PaletteStorage customBlockPaletteStorage; - - public IntSet blockEntities; - public Int2ObjectMap blocksData; + public Int2ObjectMap handlerMap; + public Int2ObjectMap nbtMap; public int[] sections = new int[0]; @@ -54,11 +52,6 @@ public class ChunkDataPacket implements ServerPacket, CacheablePacket { private final UUID identifier; private final long timestamp; - /** - * Block entities NBT, as read from raw packet data. - * Only filled by #read, and unused at the moment. - */ - public NBTCompound[] blockEntitiesNBT = new NBTCompound[0]; /** * Heightmaps NBT, as read from raw packet data. * Only filled by #read, and unused at the moment. @@ -131,28 +124,26 @@ public class ChunkDataPacket implements ServerPacket, CacheablePacket { blocks.release(); // Block entities - if (blockEntities == null) { + if (handlerMap == null || handlerMap.isEmpty()) { writer.writeVarInt(0); } else { - writer.writeVarInt(blockEntities.size()); + writer.writeVarInt(handlerMap.size()); - for (int index : blockEntities) { + for (var entry : handlerMap.int2ObjectEntrySet()) { + final int index = entry.getIntKey(); + final BlockHandler handler = entry.getValue(); final BlockPosition blockPosition = ChunkUtils.getBlockPosition(index, chunkX, chunkZ); - NBTCompound nbt = new NBTCompound() + NBTCompound nbt; + if (nbtMap != null) { + nbt = Objects.requireNonNullElseGet(nbtMap.get(index), NBTCompound::new); + } else { + nbt = new NBTCompound(); + } + nbt.setString("id", handler.getNamespaceId().asString()) .setInt("x", blockPosition.getX()) .setInt("y", blockPosition.getY()) .setInt("z", blockPosition.getZ()); - - // TODO: Handle custom blocks -// if (customBlockPaletteStorage != null) { -// final short customBlockId = customBlockPaletteStorage.getBlockAt(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ()); -// final CustomBlock customBlock = BLOCK_MANAGER.getCustomBlock(customBlockId); -// if (customBlock != null) { -// final Data data = blocksData.get(index); -// customBlock.writeBlockEntity(blockPosition, data, nbt); -// } -// } writer.writeNBT("", nbt); } } @@ -213,12 +204,17 @@ public class ChunkDataPacket implements ServerPacket, CacheablePacket { } // Block entities - int blockEntityCount = reader.readVarInt(); - blockEntities = new IntOpenHashSet(); - blockEntitiesNBT = new NBTCompound[blockEntityCount]; + final int blockEntityCount = reader.readVarInt(); + handlerMap = new Int2ObjectOpenHashMap<>(); + nbtMap = new Int2ObjectOpenHashMap<>(); for (int i = 0; i < blockEntityCount; i++) { NBTCompound tag = (NBTCompound) reader.readTag(); - blockEntitiesNBT[i] = tag; + final String id = tag.getString("id"); + // TODO retrieve handler by namespace + final int x = tag.getInt("x"); + final int y = tag.getInt("y"); + final int z = tag.getInt("z"); + // TODO add to handlerMap & nbtMap } } catch (IOException | NBTException e) { MinecraftServer.getExceptionManager().handleException(e);