From b00160eb2696418a0dae1c3f4b698ad0b43fda0b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 Jan 2025 12:41:49 +0300 Subject: [PATCH] add chunk data validity check to world.set_chunk_data --- src/logic/scripting/lua/libs/libworld.cpp | 3 ++- src/voxels/compressed_chunks.cpp | 18 ++++++++++++++++-- src/voxels/compressed_chunks.hpp | 8 +++++++- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/logic/scripting/lua/libs/libworld.cpp b/src/logic/scripting/lua/libs/libworld.cpp index f858f963..c5abf6be 100644 --- a/src/logic/scripting/lua/libs/libworld.cpp +++ b/src/logic/scripting/lua/libs/libworld.cpp @@ -5,6 +5,7 @@ #include "api_lua.hpp" #include "assets/AssetsLoader.hpp" #include "coders/json.hpp" +#include "content/Content.hpp" #include "engine/Engine.hpp" #include "files/WorldFiles.hpp" #include "files/engine_paths.hpp" @@ -181,7 +182,7 @@ static int l_set_chunk_data(lua::State* L) { return lua::pushboolean(L, false); } compressed_chunks::decode( - *chunk, buffer.data(), buffer.size() + *chunk, buffer.data(), buffer.size(), *content->getIndices() ); if (controller->getChunksController()->lighting == nullptr) { return lua::pushboolean(L, true); diff --git a/src/voxels/compressed_chunks.cpp b/src/voxels/compressed_chunks.cpp index 24cc02dd..63d3d43f 100644 --- a/src/voxels/compressed_chunks.cpp +++ b/src/voxels/compressed_chunks.cpp @@ -2,7 +2,7 @@ #include "coders/rle.hpp" #include "coders/gzip.hpp" - +#include "content/Content.hpp" #include "files/WorldFiles.hpp" inline constexpr int HAS_VOXELS = 0x1; @@ -48,7 +48,9 @@ static void read_voxel_data(ByteReader& reader, util::Buffer& dst) { extrle::decode16(rleData.data(), rleData.size(), dst.data()); } -void compressed_chunks::decode(Chunk& chunk, const ubyte* src, size_t size) { +void compressed_chunks::decode( + Chunk& chunk, const ubyte* src, size_t size, const ContentIndices& indices +) { ByteReader reader(src, size); ubyte flags = reader.get(); @@ -58,6 +60,18 @@ void compressed_chunks::decode(Chunk& chunk, const ubyte* src, size_t size) { /// world.get_chunk_data is only available in the main Lua state static util::Buffer voxelData (CHUNK_DATA_LEN); read_voxel_data(reader, voxelData); + // TODO: move somewhere in Chunk + auto src = reinterpret_cast(voxelData.data()); + for (size_t i = 0; i < CHUNK_VOL; i++) { + blockid_t id = dataio::le2h(src[i]);; + if (indices.blocks.get(id) == nullptr) { + throw std::runtime_error( + "block data corruption (chunk: " + std::to_string(chunk.x) + + ", " + std::to_string(chunk.z) + ") at " + + std::to_string(i) + " id: " + std::to_string(id) + ); + } + } chunk.decode(voxelData.data()); chunk.updateHeights(); } diff --git a/src/voxels/compressed_chunks.hpp b/src/voxels/compressed_chunks.hpp index dd00bc66..203cc5ef 100644 --- a/src/voxels/compressed_chunks.hpp +++ b/src/voxels/compressed_chunks.hpp @@ -6,6 +6,7 @@ #include +class ContentIndices; class WorldRegions; namespace compressed_chunks { @@ -15,6 +16,11 @@ namespace compressed_chunks { util::Buffer& rleBuffer ); std::vector encode(const Chunk& chunk); - void decode(Chunk& chunk, const ubyte* src, size_t size); + void decode( + Chunk& chunk, + const ubyte* src, + size_t size, + const ContentIndices& indices + ); void save(int x, int z, std::vector bytes, WorldRegions& regions); }