diff options
Diffstat (limited to 'src/World')
-rw-r--r-- | src/World/Chunk.cpp | 63 | ||||
-rw-r--r-- | src/World/Chunk.hpp | 17 | ||||
-rw-r--r-- | src/World/ChunkData.cpp | 97 | ||||
-rw-r--r-- | src/World/ChunkData.hpp | 60 | ||||
-rw-r--r-- | src/World/Region.cpp | 2 | ||||
-rw-r--r-- | src/World/Region.hpp | 2 |
6 files changed, 165 insertions, 76 deletions
diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index bf59068..07e38a4 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net> + Copyright (c) 2015-2018, Matthias Schiffer <mschiffer@universe-factory.net> All rights reserved. Redistribution and use in source and binary forms, with or without @@ -38,66 +38,9 @@ namespace MinedMap { namespace World { -Chunk::Chunk(Buffer buffer) { - size_t size = buffer.get32(); +Chunk::Chunk(const ChunkData *data) { + level = assertValue(data->getRoot().get<NBT::CompoundTag>("Level")); - Buffer buffer2(buffer.get(size), size); - - uint8_t format = buffer2.get8(); - if (format != 2) - throw std::invalid_argument("unknown chunk format"); - - inflateChunk(buffer2); - parseChunk(); - analyzeChunk(); -} - -void Chunk::inflateChunk(Buffer buffer) { - size_t outlen = 0; - uint8_t *output = nullptr; - - z_stream stream = {}; - int ret = inflateInit(&stream); - if (ret != Z_OK) - throw std::runtime_error("inflateInit() failed"); - - stream.avail_in = buffer.getRemaining(); - stream.next_in = const_cast<uint8_t *>(buffer.get(stream.avail_in)); - - while (stream.avail_in) { - outlen += 65536; - output = static_cast<uint8_t *>(std::realloc(output, outlen)); - - stream.next_out = output + stream.total_out; - stream.avail_out = outlen - stream.total_out; - - ret = inflate(&stream, Z_NO_FLUSH); - switch (ret) { - case Z_NEED_DICT: - case Z_DATA_ERROR: - case Z_MEM_ERROR: - inflateEnd(&stream); - throw std::runtime_error("inflate() failed"); - } - } - - inflateEnd(&stream); - - len = stream.total_out; - data = UniqueCPtr<uint8_t[]>(output); -} - -void Chunk::parseChunk() { - Buffer nbt(data.get(), len); - std::pair<std::string, std::shared_ptr<const NBT::Tag>> tag = NBT::Tag::readNamedTag(&nbt); - if (tag.first != "") - throw std::invalid_argument("invalid root tag"); - - root = assertValue(std::dynamic_pointer_cast<const NBT::CompoundTag>(tag.second)); - level = assertValue(root->get<NBT::CompoundTag>("Level")); -} - -void Chunk::analyzeChunk() { std::shared_ptr<const NBT::ByteTag> lightPopulatedTag = level->get<NBT::ByteTag>("LightPopulated"); bool lightPopulated = lightPopulatedTag && lightPopulatedTag->getValue(); diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index a08f9e6..d4213b3 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net> + Copyright (c) 2015-2018, Matthias Schiffer <mschiffer@universe-factory.net> All rights reserved. Redistribution and use in source and binary forms, with or without @@ -28,10 +28,8 @@ #include "Block.hpp" -#include "../Buffer.hpp" -#include "../UniqueCPtr.hpp" +#include "ChunkData.hpp" #include "../Util.hpp" -#include "../NBT/CompoundTag.hpp" #include "../NBT/ListTag.hpp" #include "../NBT/ByteTag.hpp" #include "../NBT/ByteArrayTag.hpp" @@ -53,10 +51,6 @@ public: private: - size_t len; - UniqueCPtr<uint8_t[]> data; - - std::shared_ptr<const NBT::CompoundTag> root; std::shared_ptr<const NBT::CompoundTag> level; std::shared_ptr<const NBT::ListTag<NBT::CompoundTag>> sections; @@ -106,13 +100,8 @@ private: return biomes[z*SIZE + x]; } - - void inflateChunk(Buffer buffer); - void parseChunk(); - void analyzeChunk(); - public: - Chunk(Buffer buffer); + Chunk(const ChunkData *data); const NBT::CompoundTag & getLevel() const { return *level; diff --git a/src/World/ChunkData.cpp b/src/World/ChunkData.cpp new file mode 100644 index 0000000..7eb8ea4 --- /dev/null +++ b/src/World/ChunkData.cpp @@ -0,0 +1,97 @@ +/* + Copyright (c) 2015-2018, Matthias Schiffer <mschiffer@universe-factory.net> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "ChunkData.hpp" + +#include <iostream> +#include <stdexcept> +#include <cstdlib> + +#include <zlib.h> + + +namespace MinedMap { +namespace World { + +ChunkData::ChunkData(Buffer buffer) { + size_t size = buffer.get32(); + + Buffer buffer2(buffer.get(size), size); + + uint8_t format = buffer2.get8(); + if (format != 2) + throw std::invalid_argument("unknown chunk format"); + + inflateChunk(buffer2); + parseChunk(); +} + +void ChunkData::inflateChunk(Buffer buffer) { + size_t outlen = 0; + uint8_t *output = nullptr; + + z_stream stream = {}; + int ret = inflateInit(&stream); + if (ret != Z_OK) + throw std::runtime_error("inflateInit() failed"); + + stream.avail_in = buffer.getRemaining(); + stream.next_in = const_cast<uint8_t *>(buffer.get(stream.avail_in)); + + while (stream.avail_in) { + outlen += 65536; + output = static_cast<uint8_t *>(std::realloc(output, outlen)); + + stream.next_out = output + stream.total_out; + stream.avail_out = outlen - stream.total_out; + + ret = inflate(&stream, Z_NO_FLUSH); + switch (ret) { + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: + inflateEnd(&stream); + throw std::runtime_error("inflate() failed"); + } + } + + inflateEnd(&stream); + + len = stream.total_out; + data = UniqueCPtr<uint8_t[]>(output); +} + +void ChunkData::parseChunk() { + Buffer nbt(data.get(), len); + std::pair<std::string, std::shared_ptr<const NBT::Tag>> tag = NBT::Tag::readNamedTag(&nbt); + if (tag.first != "") + throw std::invalid_argument("invalid root tag"); + + root = assertValue(std::dynamic_pointer_cast<const NBT::CompoundTag>(tag.second)); +} + +} +} diff --git a/src/World/ChunkData.hpp b/src/World/ChunkData.hpp new file mode 100644 index 0000000..5fe27c9 --- /dev/null +++ b/src/World/ChunkData.hpp @@ -0,0 +1,60 @@ +/* + Copyright (c) 2015-2018, Matthias Schiffer <mschiffer@universe-factory.net> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#pragma once + + +#include "../Buffer.hpp" +#include "../UniqueCPtr.hpp" +#include "../Util.hpp" +#include "../NBT/CompoundTag.hpp" + +#include <cstdint> + + +namespace MinedMap { +namespace World { + +class ChunkData { +private: + size_t len; + UniqueCPtr<uint8_t[]> data; + + std::shared_ptr<const NBT::CompoundTag> root; + + void inflateChunk(Buffer buffer); + void parseChunk(); + +public: + ChunkData(Buffer buffer); + + const NBT::CompoundTag & getRoot() const { + return *root; + } +}; + +} +} diff --git a/src/World/Region.cpp b/src/World/Region.cpp index 886f96b..830256e 100644 --- a/src/World/Region.cpp +++ b/src/World/Region.cpp @@ -91,7 +91,7 @@ void Region::visitChunks(const char *filename, const ChunkVisitor &visitor) { uint8_t buffer[len * 4096]; file.read((char *)buffer, len * 4096); - Chunk chunk(Buffer(buffer, len * 4096)); + ChunkData chunk(Buffer(buffer, len * 4096)); visitor(x, z, &chunk); i += len; diff --git a/src/World/Region.hpp b/src/World/Region.hpp index 7a8088f..00bfd7b 100644 --- a/src/World/Region.hpp +++ b/src/World/Region.hpp @@ -42,7 +42,7 @@ class Region { public: static const size_t SIZE = 32; - typedef std::function<void (size_t, size_t, const Chunk *)> ChunkVisitor; + typedef std::function<void (size_t, size_t, const ChunkData *)> ChunkVisitor; Region() = delete; |