diff --git a/src/items/Inventory.cpp b/src/items/Inventory.cpp index 5978f2834..2946d20ab 100644 --- a/src/items/Inventory.cpp +++ b/src/items/Inventory.cpp @@ -1,6 +1,9 @@ #include "Inventory.hpp" #include "content/ContentReport.hpp" +#include "debug/Logger.hpp" + +static debug::Logger logger("inventory"); Inventory::Inventory(int64_t id, size_t size) : id(id), slots(size) { } @@ -104,6 +107,22 @@ dv::value Inventory::serialize() const { return map; } +void Inventory::check(const ContentIndices& indices) { + for (size_t i = 0; i < slots.size(); i++) { + auto& slot = slots[i]; + if (indices.items.get(slot.getItemId()) == nullptr) { +#ifdef NDEBUG + logger.error() << "invalid item id " << slot.getItemId() + << " found in inventory #" << id << " slot #" << i + << "; will reset"; + slot.clear(); +#else + abort(); +#endif + } + } +} + void Inventory::convert(const ContentReport* report) { for (auto& slot : slots) { itemid_t id = slot.getItemId(); diff --git a/src/items/Inventory.hpp b/src/items/Inventory.hpp index 1c66fdece..80fbfecfb 100644 --- a/src/items/Inventory.hpp +++ b/src/items/Inventory.hpp @@ -39,6 +39,7 @@ public: dv::value serialize() const override; + void check(const ContentIndices& indices); void convert(const ContentReport* report); static void convert(dv::value& data, const ContentReport* report); diff --git a/src/objects/Players.cpp b/src/objects/Players.cpp index 5fc59f409..6bce34abd 100644 --- a/src/objects/Players.cpp +++ b/src/objects/Players.cpp @@ -4,6 +4,7 @@ #include #include "Player.hpp" +#include "content/Content.hpp" #include "items/Inventories.hpp" #include "world/Level.hpp" #include "world/World.hpp" @@ -87,7 +88,9 @@ Player* Players::create(int64_t id) { auto player = playerPtr.get(); add(std::move(playerPtr)); - level.inventories->store(player->getInventory()); + auto inventory = player->getInventory(); + inventory->check(*level.content.getIndices()); + level.inventories->store(std::move(inventory)); return player; } @@ -147,6 +150,7 @@ void Players::deserialize(const dv::value& src) { if (inventory->getId() == 0) { inventory->setId(level.getWorld()->getNextInventoryId()); } - level.inventories->store(player->getInventory()); + inventory->check(*level.content.getIndices()); + level.inventories->store(inventory); } } diff --git a/src/voxels/GlobalChunks.cpp b/src/voxels/GlobalChunks.cpp index 032ae17e2..75aa380ff 100644 --- a/src/voxels/GlobalChunks.cpp +++ b/src/voxels/GlobalChunks.cpp @@ -128,6 +128,7 @@ std::shared_ptr GlobalChunks::create(int x, int z, bool lighting) { chunk->flags.loaded = true; for (auto& entry : chunk->inventories) { + entry.second->check(indices); level.inventories->store(entry.second); } }