Improve chunk packet reading

This commit is contained in:
TheMode 2021-08-19 00:11:24 +02:00
parent 8c6778983b
commit 1c59186b61
4 changed files with 35 additions and 24 deletions

View File

@ -164,11 +164,7 @@ public class AnvilLoader implements IChunkLoader {
final String tileEntityID = te.getString("id"); final String tileEntityID = te.getString("id");
if (tileEntityID != null) { if (tileEntityID != null) {
var handler = BLOCK_MANAGER.getHandler(tileEntityID); final BlockHandler handler = BLOCK_MANAGER.getHandlerOrDummy(tileEntityID);
if (handler == null) {
LOGGER.warn("Block {} does not have any corresponding handler, default to dummy.", tileEntityID);
handler = BlockHandler.Dummy.get(tileEntityID);
}
block = block.withHandler(handler); block = block.withHandler(handler);
} }
// Remove anvil tags // Remove anvil tags

View File

@ -4,14 +4,18 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minestom.server.instance.block.rule.BlockPlacementRule; import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.utils.validate.Check; import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier; import java.util.function.Supplier;
public class BlockManager { public class BlockManager {
private final static Logger LOGGER = LoggerFactory.getLogger(BlockManager.class);
// Namespace -> handler supplier // Namespace -> handler supplier
private final Map<String, Supplier<BlockHandler>> blockHandlerMap = new ConcurrentHashMap<>(); private final Map<String, Supplier<BlockHandler>> blockHandlerMap = new ConcurrentHashMap<>();
@ -28,6 +32,16 @@ public class BlockManager {
return handler != null ? handler.get() : null; 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}. * Registers a {@link BlockPlacementRule}.
* *

View File

@ -192,6 +192,10 @@ public final class Palette implements PublicCloneable<Palette> {
return blocks; return blocks;
} }
public void setBlocks(long[] blocks) {
this.blocks = blocks;
}
/** /**
* Get the amount of non air blocks in this section. * Get the amount of non air blocks in this section.
* *
@ -201,6 +205,10 @@ public final class Palette implements PublicCloneable<Palette> {
return blockCount; return blockCount;
} }
public void setBlockCount(short blockCount) {
this.blockCount = blockCount;
}
public Short2ShortLinkedOpenHashMap getPaletteBlockMap() { public Short2ShortLinkedOpenHashMap getPaletteBlockMap() {
return paletteBlockMap; return paletteBlockMap;
} }

View File

@ -147,8 +147,8 @@ public class ChunkDataPacket implements ServerPacket {
@Override @Override
public void read(@NotNull BinaryReader reader) { public void read(@NotNull BinaryReader reader) {
chunkX = reader.readInt(); this.chunkX = reader.readInt();
chunkZ = reader.readInt(); this.chunkZ = reader.readInt();
int maskCount = reader.readVarInt(); int maskCount = reader.readVarInt();
long[] masks = new long[maskCount]; long[] masks = new long[maskCount];
@ -158,7 +158,7 @@ public class ChunkDataPacket implements ServerPacket {
try { try {
// TODO: Use heightmaps // TODO: Use heightmaps
// unused at the moment // unused at the moment
heightmapsNBT = (NBTCompound) reader.readTag(); this.heightmapsNBT = (NBTCompound) reader.readTag();
// Biomes // Biomes
int[] biomesIds = reader.readVarIntArray(); int[] biomesIds = reader.readVarIntArray();
@ -168,23 +168,22 @@ public class ChunkDataPacket implements ServerPacket {
} }
// Data // Data
this.sections = new HashMap<>();
int blockArrayLength = reader.readVarInt(); int blockArrayLength = reader.readVarInt();
if (maskCount > 0) { if (maskCount > 0) {
final long mask = masks[0]; // TODO support for variable size final long mask = masks[0]; // TODO support for variable size
for (int sectionIndex = 0; sectionIndex < CHUNK_SECTION_COUNT; sectionIndex++) { for (int sectionIndex = 0; sectionIndex < CHUNK_SECTION_COUNT; sectionIndex++) {
boolean hasSection = (mask & 1 << sectionIndex) != 0; final boolean hasSection = (mask & 1 << sectionIndex) != 0;
if (!hasSection) if (!hasSection) continue;
continue;
final Section section = sections.computeIfAbsent(sectionIndex, i -> new Section()); final Section section = sections.computeIfAbsent(sectionIndex, i -> new Section());
final Palette palette = section.getPalette(); final Palette palette = section.getPalette();
short blockCount = reader.readShort(); final short blockCount = reader.readShort();
byte bitsPerEntry = reader.readByte(); palette.setBlockCount(blockCount);
final byte bitsPerEntry = reader.readByte();
// Resize palette if necessary // Resize palette if necessary
if (bitsPerEntry > palette.getBitsPerEntry()) { if (bitsPerEntry > palette.getBitsPerEntry()) {
palette.resize(bitsPerEntry); palette.resize(bitsPerEntry);
} }
// Retrieve palette values // Retrieve palette values
if (bitsPerEntry < 9) { if (bitsPerEntry < 9) {
int paletteSize = reader.readVarInt(); int paletteSize = reader.readVarInt();
@ -194,24 +193,18 @@ public class ChunkDataPacket implements ServerPacket {
palette.getBlockPaletteMap().put((short) paletteValue, (short) i); palette.getBlockPaletteMap().put((short) paletteValue, (short) i);
} }
} }
// Read blocks // Read blocks
int dataLength = reader.readVarInt(); palette.setBlocks(reader.readLongArray());
long[] data = palette.getBlocks();
for (int i = 0; i < dataLength; i++) {
data[i] = reader.readLong();
}
} }
} }
// Block entities // Block entities
final int blockEntityCount = reader.readVarInt(); final int blockEntityCount = reader.readVarInt();
this.entries = new Int2ObjectOpenHashMap<>(blockEntityCount);
entries = new Int2ObjectOpenHashMap<>();
for (int i = 0; i < blockEntityCount; i++) { for (int i = 0; i < blockEntityCount; i++) {
NBTCompound tag = (NBTCompound) reader.readTag(); NBTCompound tag = (NBTCompound) reader.readTag();
final String id = tag.getString("id"); 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 x = tag.getInt("x");
final int y = tag.getInt("y"); final int y = tag.getInt("y");
final int z = tag.getInt("z"); final int z = tag.getInt("z");