From 1c59186b61334810010ecc1c966fcc97b103f3b6 Mon Sep 17 00:00:00 2001 From: TheMode Date: Thu, 19 Aug 2021 00:11:24 +0200 Subject: [PATCH] Improve chunk packet reading --- .../minestom/server/instance/AnvilLoader.java | 6 +--- .../server/instance/block/BlockManager.java | 14 +++++++++ .../server/instance/palette/Palette.java | 8 +++++ .../packet/server/play/ChunkDataPacket.java | 31 +++++++------------ 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/main/java/net/minestom/server/instance/AnvilLoader.java b/src/main/java/net/minestom/server/instance/AnvilLoader.java index 265bd0fd8..6a813afdb 100644 --- a/src/main/java/net/minestom/server/instance/AnvilLoader.java +++ b/src/main/java/net/minestom/server/instance/AnvilLoader.java @@ -164,11 +164,7 @@ public class AnvilLoader implements IChunkLoader { final String tileEntityID = te.getString("id"); if (tileEntityID != null) { - var handler = BLOCK_MANAGER.getHandler(tileEntityID); - if (handler == null) { - LOGGER.warn("Block {} does not have any corresponding handler, default to dummy.", tileEntityID); - handler = BlockHandler.Dummy.get(tileEntityID); - } + final BlockHandler handler = BLOCK_MANAGER.getHandlerOrDummy(tileEntityID); block = block.withHandler(handler); } // Remove anvil tags diff --git a/src/main/java/net/minestom/server/instance/block/BlockManager.java b/src/main/java/net/minestom/server/instance/block/BlockManager.java index 105164583..446fe6dea 100644 --- a/src/main/java/net/minestom/server/instance/block/BlockManager.java +++ b/src/main/java/net/minestom/server/instance/block/BlockManager.java @@ -4,14 +4,18 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.minestom.server.instance.block.rule.BlockPlacementRule; import net.minestom.server.utils.validate.Check; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; public class BlockManager { + private final static Logger LOGGER = LoggerFactory.getLogger(BlockManager.class); // Namespace -> handler supplier private final Map> blockHandlerMap = new ConcurrentHashMap<>(); @@ -28,6 +32,16 @@ public class BlockManager { return handler != null ? handler.get() : null; } + @ApiStatus.Internal + public synchronized @Nullable BlockHandler getHandlerOrDummy(@NotNull String namespace) { + BlockHandler handler = getHandler(namespace); + if (handler == null) { + LOGGER.warn("Block {} does not have any corresponding handler, default to dummy.", namespace); + handler = BlockHandler.Dummy.get(namespace); + } + return handler; + } + /** * Registers a {@link BlockPlacementRule}. * diff --git a/src/main/java/net/minestom/server/instance/palette/Palette.java b/src/main/java/net/minestom/server/instance/palette/Palette.java index 906e08756..69b21c497 100644 --- a/src/main/java/net/minestom/server/instance/palette/Palette.java +++ b/src/main/java/net/minestom/server/instance/palette/Palette.java @@ -192,6 +192,10 @@ public final class Palette implements PublicCloneable { return blocks; } + public void setBlocks(long[] blocks) { + this.blocks = blocks; + } + /** * Get the amount of non air blocks in this section. * @@ -201,6 +205,10 @@ public final class Palette implements PublicCloneable { return blockCount; } + public void setBlockCount(short blockCount) { + this.blockCount = blockCount; + } + public Short2ShortLinkedOpenHashMap getPaletteBlockMap() { return paletteBlockMap; } 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 c2d698e9c..115368986 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 @@ -147,8 +147,8 @@ public class ChunkDataPacket implements ServerPacket { @Override public void read(@NotNull BinaryReader reader) { - chunkX = reader.readInt(); - chunkZ = reader.readInt(); + this.chunkX = reader.readInt(); + this.chunkZ = reader.readInt(); int maskCount = reader.readVarInt(); long[] masks = new long[maskCount]; @@ -158,7 +158,7 @@ public class ChunkDataPacket implements ServerPacket { try { // TODO: Use heightmaps // unused at the moment - heightmapsNBT = (NBTCompound) reader.readTag(); + this.heightmapsNBT = (NBTCompound) reader.readTag(); // Biomes int[] biomesIds = reader.readVarIntArray(); @@ -168,23 +168,22 @@ public class ChunkDataPacket implements ServerPacket { } // Data + this.sections = new HashMap<>(); int blockArrayLength = reader.readVarInt(); if (maskCount > 0) { final long mask = masks[0]; // TODO support for variable size for (int sectionIndex = 0; sectionIndex < CHUNK_SECTION_COUNT; sectionIndex++) { - boolean hasSection = (mask & 1 << sectionIndex) != 0; - if (!hasSection) - continue; + final boolean hasSection = (mask & 1 << sectionIndex) != 0; + if (!hasSection) continue; final Section section = sections.computeIfAbsent(sectionIndex, i -> new Section()); final Palette palette = section.getPalette(); - short blockCount = reader.readShort(); - byte bitsPerEntry = reader.readByte(); - + final short blockCount = reader.readShort(); + palette.setBlockCount(blockCount); + final byte bitsPerEntry = reader.readByte(); // Resize palette if necessary if (bitsPerEntry > palette.getBitsPerEntry()) { palette.resize(bitsPerEntry); } - // Retrieve palette values if (bitsPerEntry < 9) { int paletteSize = reader.readVarInt(); @@ -194,24 +193,18 @@ public class ChunkDataPacket implements ServerPacket { palette.getBlockPaletteMap().put((short) paletteValue, (short) i); } } - // Read blocks - int dataLength = reader.readVarInt(); - long[] data = palette.getBlocks(); - for (int i = 0; i < dataLength; i++) { - data[i] = reader.readLong(); - } + palette.setBlocks(reader.readLongArray()); } } // Block entities final int blockEntityCount = reader.readVarInt(); - - entries = new Int2ObjectOpenHashMap<>(); + this.entries = new Int2ObjectOpenHashMap<>(blockEntityCount); for (int i = 0; i < blockEntityCount; i++) { NBTCompound tag = (NBTCompound) reader.readTag(); final String id = tag.getString("id"); - // TODO retrieve handler by namespace + final BlockHandler handler = MinecraftServer.getBlockManager().getHandlerOrDummy(id); final int x = tag.getInt("x"); final int y = tag.getInt("y"); final int z = tag.getInt("z");