diff options
Diffstat (limited to 'code/World.cpp')
-rw-r--r-- | code/World.cpp | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/code/World.cpp b/code/World.cpp new file mode 100644 index 0000000..c19f88c --- /dev/null +++ b/code/World.cpp @@ -0,0 +1,107 @@ +#include <iostream> +#include <bitset> +#include "World.hpp" + +void World::ParseChunkData(Packet packet) { + int chunkX = packet.GetField(0).GetInt(); + int chunkZ = packet.GetField(1).GetInt(); + bool isGroundContinuous = packet.GetField(2).GetBool(); + std::bitset<16> bitmask(packet.GetField(3).GetVarInt()); + int entities = packet.GetField(5).GetVarInt(); + + size_t dataLen = packet.GetField(5).GetLength(); + byte *content = new byte[dataLen]; + byte *contentOrigPtr = content; + packet.GetField(5).CopyToBuff(content); + + if (isGroundContinuous) + dataLen -= 256; + + byte *biomes = content + packet.GetField(5).GetLength() - 256; + for (int i = 0; i < 16; i++) { + if (bitmask[i]) { + size_t len = 0; + m_sections[PositionI(chunkX, chunkZ, i)] = ParseSection(content, len); + m_sectionToParse.push(m_sections.find(PositionI(chunkX, chunkZ, i))); + m_parseSectionWaiter.notify_one(); + content += len; + } + } + delete[] contentOrigPtr; +} + +Section World::ParseSection(byte *data, size_t &dataLen) { + dataLen = 0; + + Field fBitsPerBlock = FieldParser::Parse(UnsignedByte, data); + byte bitsPerBlock = fBitsPerBlock.GetUByte(); + data += fBitsPerBlock.GetLength(); + dataLen += fBitsPerBlock.GetLength(); + + Field fPaletteLength = FieldParser::Parse(VarInt, data); + int paletteLength = fPaletteLength.GetVarInt(); + data += fPaletteLength.GetLength(); + dataLen += fPaletteLength.GetLength(); + + std::vector<unsigned short> palette; + if (paletteLength > 0) { + for (unsigned char i = 0; i < paletteLength; i++) { + endswap(&i); + Field f = FieldParser::Parse(VarInt, data); + data += f.GetLength(); + dataLen += f.GetLength(); + palette.push_back(f.GetVarInt()); + endswap(&i); + } + } + + Field fDataLength = FieldParser::Parse(VarInt, data); + data += fDataLength.GetLength(); + dataLen += fDataLength.GetLength(); + + int dataLength = fDataLength.GetVarInt(); + size_t dataSize = dataLength * 8; + dataLen += dataSize; + byte *dataBlocks = data; + + data += 2048; + dataLen += 2048; + byte *dataLight = data; + + byte *dataSky = nullptr; + if (m_dimension == 0) { + data += 2048; + dataLen += 2048; + dataSky = data; + } + + return Section(dataBlocks, dataSize, dataLight, dataSky, bitsPerBlock, palette); +} + +World::~World() { + isContinue = false; + m_parseSectionWaiter.notify_all(); + m_sectionParseThread.join(); +} + +void World::SectionParsingThread() { + while (isContinue) { + std::unique_lock<std::mutex> sectionParseLocker(m_parseSectionMutex); + m_parseSectionWaiter.wait(sectionParseLocker); + while (m_sectionToParse.size() == 0 && isContinue) { + m_parseSectionWaiter.wait(sectionParseLocker); + } + while (m_sectionToParse.size() > 0) { + auto it = m_sectionToParse.front(); + m_sectionToParse.pop(); + it->second.Parse(); + /*std::cout << "Parsed chunk" << it->first.GetX() << "x" << it->first.GetY() << "x" << it->first.GetZ() + << std::endl;*/ + } + } +} + +World::World() { + m_sectionParseThread = std::thread(&World::SectionParsingThread, this); +} + |