5 #include "../ClientHandle.h"
6 #include "../WorldStorage/FastNBT.h"
30 return { Mask, Present };
35 return (a_BlockType << 4) | a_Meta;
63 m_Dimension(a_Dimension)
73 for (
const auto & Client : a_SendTo)
121 UNREACHABLE(
"Unknown chunk data serialization version");
127 Cache.Engaged =
false;
137 auto & Cache =
m_Cache[
static_cast<size_t>(a_CacheVersion)];
141 a_Client->SendChunkData(a_ChunkX, a_ChunkZ, Cache.ToSend);
145 switch (a_CacheVersion)
149 Serialize47(a_ChunkX, a_ChunkZ, a_BlockData, a_LightData, a_BiomeMap);
154 Serialize107(a_ChunkX, a_ChunkZ, a_BlockData, a_LightData, a_BiomeMap);
159 Serialize110(a_ChunkX, a_ChunkZ, a_BlockData, a_LightData, a_BiomeMap);
164 Serialize393<&Palette393>(a_ChunkX, a_ChunkZ, a_BlockData, a_LightData, a_BiomeMap);
169 Serialize393<&Palette401>(a_ChunkX, a_ChunkZ, a_BlockData, a_LightData, a_BiomeMap);
174 Serialize477(a_ChunkX, a_ChunkZ, a_BlockData, a_LightData, a_BiomeMap);
181 a_Client->SendChunkData(a_ChunkX, a_ChunkZ, Cache.ToSend);
192 const auto Bitmask = GetSectionBitmask(a_BlockData, a_LightData);
207 const size_t ChunkSize = (
219 const bool BlocksExist = Blocks !=
nullptr;
220 const bool MetasExist = Metas !=
nullptr;
234 if (BlockLights ==
nullptr)
247 if (SkyLights ==
nullptr)
283 static constexpr
UInt8 BitsPerEntry = 13;
286 const auto Bitmask = GetSectionBitmask(a_BlockData, a_LightData);
295 size_t ChunkSectionSize = (
299 ChunkSectionDataArraySize * 8 +
310 const size_t ChunkSize = (
311 ChunkSectionSize * Bitmask.second +
324 WriteBlockSectionSeamless<&PaletteLegacy>(Blocks, Metas, BitsPerEntry);
341 static constexpr
UInt8 BitsPerEntry = 13;
344 const auto Bitmask = GetSectionBitmask(a_BlockData, a_LightData);
353 size_t ChunkSectionSize = (
357 ChunkSectionDataArraySize * 8 +
368 const size_t ChunkSize = (
369 ChunkSectionSize * Bitmask.second +
382 WriteBlockSectionSeamless<&PaletteLegacy>(Blocks, Metas, BitsPerEntry);
397 template <auto Palette>
403 static constexpr
UInt8 BitsPerEntry = 14;
406 const auto Bitmask = GetSectionBitmask(a_BlockData, a_LightData);
415 size_t ChunkSectionSize = (
418 ChunkSectionDataArraySize * 8 +
429 const size_t ChunkSize = (
430 ChunkSectionSize * Bitmask.second +
442 WriteBlockSectionSeamless<Palette>(Blocks, Metas, BitsPerEntry);
447 for (
size_t i = 0; i != BiomeDataSize; i++)
465 static constexpr
UInt8 BitsPerEntry = 14;
468 const auto Bitmask = GetSectionBitmask(a_BlockData, a_LightData);
486 const size_t ChunkSectionSize = (
490 ChunkSectionDataArraySize * 8
494 const size_t ChunkSize = (
495 ChunkSectionSize * Bitmask.second +
508 WriteBlockSectionSeamless<&Palette477>(Blocks, Metas, BitsPerEntry);
512 for (
size_t i = 0; i != BiomeDataSize; i++)
525 template <auto Palette>
531 ASSERT(a_BitsPerEntry < 64);
534 unsigned char BitIndex = 0;
536 const bool BlocksExist = a_Blocks !=
nullptr;
537 const bool MetasExist = a_Metas !=
nullptr;
543 const auto Value = Palette(
BlockType, BlockMeta);
546 Buffer |=
static_cast<UInt64>(Value) << BitIndex;
549 const auto Remaining =
static_cast<char>(a_BitsPerEntry - (64 - BitIndex));
556 Buffer =
static_cast<UInt64>(Value >> (a_BitsPerEntry - Remaining));
557 BitIndex =
static_cast<unsigned char>(Remaining);
562 BitIndex += a_BitsPerEntry;
578 if (a_BlockLights ==
nullptr)
590 if (a_SkyLights ==
nullptr)
#define ChunkDef_ForEachSection(BlockData, LightData, Callback)
Invokes the callback functor for every chunk section containing at least one present block or light s...
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
unsigned char BLOCKTYPE
The datatype used by blockdata.
eDimension
Dimension of a world.
unsigned long long UInt64
#define KiB
Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it,...
UInt32 From(const BlockState Block)
UInt32 From(const BlockState Block)
UInt32 From(const BlockState Block)
BlockState FromBlock(const BLOCKTYPE Block, const NIBBLETYPE Meta)
void CommitRead(void)
Removes the bytes that have been read from the ringbuffer.
bool WriteBEUInt32(UInt32 a_Value)
bool WriteBEInt32(Int32 a_Value)
bool WriteBEInt16(Int16 a_Value)
bool WriteBEUInt64(UInt64 a_Value)
bool WriteBuf(const void *a_Buffer, size_t a_Count)
Writes a_Count bytes into a_Buffer; returns true if successful.
bool WriteBool(bool a_Value)
bool WriteVarInt32(UInt32 a_Value)
static size_t GetVarIntSize(UInt32 a_Value)
Gets the number of bytes that are needed to represent the given VarInt.
bool Write(const void *a_Bytes, size_t a_Count)
Writes the bytes specified to the ringbuffer.
bool WriteBEUInt16(UInt16 a_Value)
bool WriteBEUInt8(UInt8 a_Value)
decltype(m_Blocks)::Type BlockArray
static constexpr size_t SectionBlockCount
decltype(m_Metas)::Type MetaArray
static constexpr NIBBLETYPE DefaultSkyLightValue
decltype(m_BlockLights)::Type LightArray
static constexpr NIBBLETYPE DefaultBlockLightValue
static constexpr size_t SectionLightCount
static NIBBLETYPE ExpandNibble(const NIBBLETYPE *const a_Buffer, const size_t a_Index)
void ReadFrom(cByteBuffer &Buffer)
void WriteLightSectionGrouped(const ChunkLightData::LightArray *a_BlockLights, const ChunkLightData::LightArray *a_SkyLights)
Copies all lights in a chunk section into the packet, block light followed immediately by sky light.
void WriteBlockSectionSeamless(const ChunkBlockData::BlockArray *a_Blocks, const ChunkBlockData::MetaArray *a_Metas, UInt8 a_BitsPerEntry)
Writes all blocks in a chunk section into a series of Int64.
CircularBufferCompressor m_Compressor
A compressor used to compress the chunk data.
void Serialize47(int a_ChunkX, int a_ChunkZ, const ChunkBlockData &a_BlockData, const ChunkLightData &a_LightData, const unsigned char *a_BiomeMap)
void Serialize393(int a_ChunkX, int a_ChunkZ, const ChunkBlockData &a_BlockData, const ChunkLightData &a_LightData, const unsigned char *a_BiomeMap)
void Serialize(const ClientHandles::value_type &a_Client, int a_ChunkX, int a_ChunkZ, const ChunkBlockData &a_BlockData, const ChunkLightData &a_LightData, const unsigned char *a_BiomeMap, CacheVersion a_CacheVersion)
Serialises the given chunk, storing the result into the given cache entry, and sends the data.
cChunkDataSerializer(eDimension a_Dimension)
void Serialize110(int a_ChunkX, int a_ChunkZ, const ChunkBlockData &a_BlockData, const ChunkLightData &a_LightData, const unsigned char *a_BiomeMap)
CacheVersion
Enum to collapse protocol versions into a contiguous index.
const eDimension m_Dimension
The dimension for the World this Serializer is tied to.
std::vector< std::shared_ptr< cClientHandle > > ClientHandles
void CompressPacketInto(ChunkDataCache &a_Cache)
Finalises the data, compresses it if required, and stores it into cache.
void SendToClients(int a_ChunkX, int a_ChunkZ, const ChunkBlockData &a_BlockData, const ChunkLightData &a_LightData, const unsigned char *a_BiomeMap, const ClientHandles &a_SendTo)
For each client, serializes the chunk into their protocol version and sends it.
cByteBuffer m_Packet
A staging area used to construct the chunk packet, persistent to avoid reallocating.
void Serialize477(int a_ChunkX, int a_ChunkZ, const ChunkBlockData &a_BlockData, const ChunkLightData &a_LightData, const unsigned char *a_BiomeMap)
void Serialize107(int a_ChunkX, int a_ChunkZ, const ChunkBlockData &a_BlockData, const ChunkLightData &a_LightData, const unsigned char *a_BiomeMap)
std::array< ChunkDataCache, static_cast< size_t >CacheVersion::Last)+1 > m_Cache
A cache, mapping protocol version to a fully serialised chunk.
A single cache entry containing the raw data, compressed data, and a validity flag.
ContiguousByteBuffer ToSend
Version
The protocol version number, received from the client in the Handshake packet.
static void CompressPacket(CircularBufferCompressor &a_Packet, ContiguousByteBuffer &a_Compressed)
Compress the packet.
ContiguousByteBufferView GetResult(void) const