Merge branch 'main' into blocks-metadata
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "content/ContentReport.hpp"
|
||||
#include "files/compatibility.hpp"
|
||||
#include "data/dynamic.hpp"
|
||||
#include "debug/Logger.hpp"
|
||||
#include "files/files.hpp"
|
||||
#include "objects/Player.hpp"
|
||||
@@ -184,8 +183,8 @@ void WorldConverter::convertInventories(const fs::path& file, int x, int z) cons
|
||||
void WorldConverter::convertPlayer(const fs::path& file) const {
|
||||
logger.info() << "converting player " << file.u8string();
|
||||
auto map = files::read_json(file);
|
||||
Player::convert(map.get(), report.get());
|
||||
files::write_json(file, map.get());
|
||||
Player::convert(map, report.get());
|
||||
files::write_json(file, map);
|
||||
}
|
||||
|
||||
void WorldConverter::convert(const ConvertTask& task) const {
|
||||
|
||||
+30
-36
@@ -13,7 +13,6 @@
|
||||
#include "constants.hpp"
|
||||
#include "content/Content.hpp"
|
||||
#include "core_defs.hpp"
|
||||
#include "data/dynamic.hpp"
|
||||
#include "debug/Logger.hpp"
|
||||
#include "items/Inventory.hpp"
|
||||
#include "items/ItemDef.hpp"
|
||||
@@ -104,24 +103,24 @@ void WorldFiles::writePacks(const std::vector<ContentPack>& packs) {
|
||||
|
||||
template <class T>
|
||||
static void write_indices(
|
||||
const ContentUnitIndices<T>& indices, dynamic::List& list
|
||||
const ContentUnitIndices<T>& indices, dv::value& list
|
||||
) {
|
||||
for (auto unit : indices.getIterable()) {
|
||||
list.put(unit->name);
|
||||
list.add(unit->name);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldFiles::writeIndices(const ContentIndices* indices) {
|
||||
dynamic::Map root;
|
||||
root.put("region-version", REGION_FORMAT_VERSION);
|
||||
write_indices(indices->blocks, root.putList("blocks"));
|
||||
write_indices(indices->items, root.putList("items"));
|
||||
write_indices(indices->entities, root.putList("entities"));
|
||||
files::write_json(getIndicesFile(), &root);
|
||||
dv::value root = dv::object();
|
||||
root["region-version"] = REGION_FORMAT_VERSION;
|
||||
write_indices(indices->blocks, root.list("blocks"));
|
||||
write_indices(indices->items, root.list("items"));
|
||||
write_indices(indices->entities, root.list("entities"));
|
||||
files::write_json(getIndicesFile(), root);
|
||||
}
|
||||
|
||||
void WorldFiles::writeWorldInfo(const WorldInfo& info) {
|
||||
files::write_json(getWorldFile(), info.serialize().get());
|
||||
files::write_json(getWorldFile(), info.serialize());
|
||||
}
|
||||
|
||||
std::optional<WorldInfo> WorldFiles::readWorldInfo() {
|
||||
@@ -132,23 +131,22 @@ std::optional<WorldInfo> WorldFiles::readWorldInfo() {
|
||||
}
|
||||
auto root = files::read_json(file);
|
||||
WorldInfo info {};
|
||||
info.deserialize(root.get());
|
||||
info.deserialize(root);
|
||||
return info;
|
||||
}
|
||||
|
||||
static void read_resources_data(
|
||||
const Content* content, const dynamic::List_sptr& list, ResourceType type
|
||||
const Content* content, const dv::value& list, ResourceType type
|
||||
) {
|
||||
const auto& indices = content->getIndices(type);
|
||||
for (size_t i = 0; i < list->size(); i++) {
|
||||
auto map = list->map(i);
|
||||
std::string name;
|
||||
map->str("name", name);
|
||||
for (size_t i = 0; i < list.size(); i++) {
|
||||
auto& map = list[i];
|
||||
const auto& name = map["name"].asString();
|
||||
size_t index = indices.indexOf(name);
|
||||
if (index == ResourceIndices::MISSING) {
|
||||
logger.warning() << "discard " << name;
|
||||
} else {
|
||||
indices.saveData(index, map->map("saved"));
|
||||
indices.saveData(index, map["saved"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,11 +158,9 @@ bool WorldFiles::readResourcesData(const Content* content) {
|
||||
return false;
|
||||
}
|
||||
auto root = files::read_json(file);
|
||||
for (const auto& [key, _] : root->values) {
|
||||
for (const auto& [key, arr] : root.asObject()) {
|
||||
if (auto resType = ResourceType_from(key)) {
|
||||
if (auto arr = root->list(key)) {
|
||||
read_resources_data(content, arr, *resType);
|
||||
}
|
||||
read_resources_data(content, arr, *resType);
|
||||
} else {
|
||||
logger.warning() << "unknown resource type: " << key;
|
||||
}
|
||||
@@ -179,35 +175,33 @@ void WorldFiles::patchIndicesVersion(const std::string& field, uint version) {
|
||||
return;
|
||||
}
|
||||
auto root = files::read_json(file);
|
||||
root->put(field, version);
|
||||
files::write_json(file, root.get(), true);
|
||||
root[field] = version;
|
||||
files::write_json(file, root, true);
|
||||
}
|
||||
|
||||
static void erase_pack_indices(dynamic::Map* root, const std::string& id) {
|
||||
static void erase_pack_indices(dv::value& root, const std::string& id) {
|
||||
auto prefix = id + ":";
|
||||
auto blocks = root->list("blocks");
|
||||
for (uint i = 0; i < blocks->size(); i++) {
|
||||
auto name = blocks->str(i);
|
||||
auto& blocks = root["blocks"];
|
||||
for (uint i = 0; i < blocks.size(); i++) {
|
||||
auto name = blocks[i].asString();
|
||||
if (name.find(prefix) != 0) continue;
|
||||
auto value = blocks->getValueWriteable(i);
|
||||
*value = CORE_AIR;
|
||||
blocks[i] = CORE_AIR;
|
||||
}
|
||||
|
||||
auto items = root->list("items");
|
||||
for (uint i = 0; i < items->size(); i++) {
|
||||
auto name = items->str(i);
|
||||
auto& items = root["items"];
|
||||
for (uint i = 0; i < items.size(); i++) {
|
||||
auto& name = items[i].asString();
|
||||
if (name.find(prefix) != 0) continue;
|
||||
auto value = items->getValueWriteable(i);
|
||||
*value = CORE_EMPTY;
|
||||
items[i] = CORE_EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldFiles::removeIndices(const std::vector<std::string>& packs) {
|
||||
auto root = files::read_json(getIndicesFile());
|
||||
for (const auto& id : packs) {
|
||||
erase_pack_indices(root.get(), id);
|
||||
erase_pack_indices(root, id);
|
||||
}
|
||||
files::write_json(getIndicesFile(), root.get());
|
||||
files::write_json(getIndicesFile(), root);
|
||||
}
|
||||
|
||||
fs::path WorldFiles::getFolder() const {
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
#include <vector>
|
||||
|
||||
#include "coders/byte_utils.hpp"
|
||||
#include "data/dynamic.hpp"
|
||||
#include "coders/rle.hpp"
|
||||
#include "coders/binary_json.hpp"
|
||||
#include "items/Inventory.hpp"
|
||||
#include "maths/voxmaths.hpp"
|
||||
#include "util/data_io.hpp"
|
||||
|
||||
#define REGION_FORMAT_MAGIC ".VOXREG"
|
||||
|
||||
WorldRegion::WorldRegion()
|
||||
: chunksData(
|
||||
std::make_unique<std::unique_ptr<ubyte[]>[]>(REGION_CHUNKS_COUNT)
|
||||
@@ -109,7 +112,7 @@ static std::unique_ptr<ubyte[]> write_inventories(
|
||||
for (auto& entry : inventories) {
|
||||
builder.putInt32(entry.first);
|
||||
auto map = entry.second->serialize();
|
||||
auto bytes = json::to_binary(map.get(), true);
|
||||
auto bytes = json::to_binary(map, true);
|
||||
builder.putInt32(bytes.size());
|
||||
builder.put(bytes.data(), bytes.size());
|
||||
}
|
||||
@@ -130,7 +133,7 @@ static chunk_inventories_map load_inventories(const ubyte* src, uint32_t size) {
|
||||
auto map = json::from_binary(reader.pointer(), size);
|
||||
reader.skip(size);
|
||||
auto inv = std::make_shared<Inventory>(0, 0);
|
||||
inv->deserialize(map.get());
|
||||
inv->deserialize(map);
|
||||
inventories[index] = inv;
|
||||
}
|
||||
return inventories;
|
||||
@@ -237,7 +240,7 @@ void WorldRegions::processInventories(
|
||||
});
|
||||
}
|
||||
|
||||
dynamic::Map_sptr WorldRegions::fetchEntities(int x, int z) {
|
||||
dv::value WorldRegions::fetchEntities(int x, int z) {
|
||||
if (generatorTestMode) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -248,7 +251,7 @@ dynamic::Map_sptr WorldRegions::fetchEntities(int x, int z) {
|
||||
return nullptr;
|
||||
}
|
||||
auto map = json::from_binary(data, bytesSize);
|
||||
if (map->size() == 0) {
|
||||
if (map.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return map;
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "constants.hpp"
|
||||
#include "typedefs.hpp"
|
||||
#include "data/dynamic_fwd.hpp"
|
||||
#include "util/BufferPool.hpp"
|
||||
#include "voxels/Chunk.hpp"
|
||||
#include "maths/voxmaths.hpp"
|
||||
@@ -223,7 +221,7 @@ public:
|
||||
/// @param x chunk.x
|
||||
/// @param z chunk.z
|
||||
/// @return map with entities list as "data"
|
||||
dynamic::Map_sptr fetchEntities(int x, int z);
|
||||
dv::value fetchEntities(int x, int z);
|
||||
|
||||
/// @brief Load, process and save processed region chunks data
|
||||
/// @param x region X
|
||||
|
||||
+6
-7
@@ -11,7 +11,6 @@
|
||||
#include "coders/gzip.hpp"
|
||||
#include "coders/json.hpp"
|
||||
#include "coders/toml.hpp"
|
||||
#include "data/dynamic.hpp"
|
||||
#include "util/stringutil.hpp"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
@@ -122,30 +121,30 @@ bool files::write_string(const fs::path& filename, const std::string content) {
|
||||
}
|
||||
|
||||
bool files::write_json(
|
||||
const fs::path& filename, const dynamic::Map* obj, bool nice
|
||||
const fs::path& filename, const dv::value& obj, bool nice
|
||||
) {
|
||||
return files::write_string(filename, json::stringify(obj, nice, " "));
|
||||
}
|
||||
|
||||
bool files::write_binary_json(
|
||||
const fs::path& filename, const dynamic::Map* obj, bool compression
|
||||
const fs::path& filename, const dv::value& obj, bool compression
|
||||
) {
|
||||
auto bytes = json::to_binary(obj, compression);
|
||||
return files::write_bytes(filename, bytes.data(), bytes.size());
|
||||
}
|
||||
|
||||
std::shared_ptr<dynamic::Map> files::read_json(const fs::path& filename) {
|
||||
dv::value files::read_json(const fs::path& filename) {
|
||||
std::string text = files::read_string(filename);
|
||||
return json::parse(filename.string(), text);
|
||||
}
|
||||
|
||||
std::shared_ptr<dynamic::Map> files::read_binary_json(const fs::path& file) {
|
||||
dv::value files::read_binary_json(const fs::path& file) {
|
||||
size_t size;
|
||||
std::unique_ptr<ubyte[]> bytes(files::read_bytes(file, size));
|
||||
auto bytes = files::read_bytes(file, size);
|
||||
return json::from_binary(bytes.get(), size);
|
||||
}
|
||||
|
||||
std::shared_ptr<dynamic::Map> files::read_toml(const fs::path& file) {
|
||||
dv::value files::read_toml(const fs::path& file) {
|
||||
return toml::parse(file.u8string(), files::read_string(file));
|
||||
}
|
||||
|
||||
|
||||
+6
-9
@@ -7,14 +7,11 @@
|
||||
#include <vector>
|
||||
|
||||
#include "typedefs.hpp"
|
||||
#include "data/dv.hpp"
|
||||
#include "util/Buffer.hpp"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace dynamic {
|
||||
class Map;
|
||||
}
|
||||
|
||||
namespace files {
|
||||
/// @brief Read-only random access file
|
||||
class rafile {
|
||||
@@ -47,7 +44,7 @@ namespace files {
|
||||
/// @param nice if true, human readable format will be used, otherwise
|
||||
/// minimal
|
||||
bool write_json(
|
||||
const fs::path& filename, const dynamic::Map* obj, bool nice = true
|
||||
const fs::path& filename, const dv::value& obj, bool nice = true
|
||||
);
|
||||
|
||||
/// @brief Write dynamic data to the binary JSON file
|
||||
@@ -55,7 +52,7 @@ namespace files {
|
||||
/// @param compressed use gzip compression
|
||||
bool write_binary_json(
|
||||
const fs::path& filename,
|
||||
const dynamic::Map* obj,
|
||||
const dv::value& obj,
|
||||
bool compressed = false
|
||||
);
|
||||
|
||||
@@ -67,8 +64,8 @@ namespace files {
|
||||
|
||||
/// @brief Read JSON or BJSON file
|
||||
/// @param file *.json or *.bjson file
|
||||
std::shared_ptr<dynamic::Map> read_json(const fs::path& file);
|
||||
std::shared_ptr<dynamic::Map> read_binary_json(const fs::path& file);
|
||||
std::shared_ptr<dynamic::Map> read_toml(const fs::path& file);
|
||||
dv::value read_json(const fs::path& file);
|
||||
dv::value read_binary_json(const fs::path& file);
|
||||
dv::value read_toml(const fs::path& file);
|
||||
std::vector<std::string> read_list(const fs::path& file);
|
||||
}
|
||||
|
||||
+35
-21
@@ -80,12 +80,13 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) {
|
||||
builder.add("do-write-lights", &settings.debug.doWriteLights);
|
||||
}
|
||||
|
||||
dynamic::Value SettingsHandler::getValue(const std::string& name) const {
|
||||
dv::value SettingsHandler::getValue(const std::string& name) const {
|
||||
auto found = map.find(name);
|
||||
if (found == map.end()) {
|
||||
throw std::runtime_error("setting '" + name + "' does not exist");
|
||||
}
|
||||
auto setting = found->second;
|
||||
|
||||
if (auto number = dynamic_cast<NumberSetting*>(setting)) {
|
||||
return static_cast<number_t>(number->get());
|
||||
} else if (auto integer = dynamic_cast<IntegerSetting*>(setting)) {
|
||||
@@ -121,20 +122,26 @@ bool SettingsHandler::has(const std::string& name) const {
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void set_numeric_value(T* setting, const dynamic::Value& value) {
|
||||
if (auto num = std::get_if<integer_t>(&value)) {
|
||||
setting->set(*num);
|
||||
} else if (auto num = std::get_if<number_t>(&value)) {
|
||||
setting->set(*num);
|
||||
} else if (auto flag = std::get_if<bool>(&value)) {
|
||||
setting->set(*flag);
|
||||
} else {
|
||||
throw std::runtime_error("type error, numeric value expected");
|
||||
static void set_numeric_value(T* setting, const dv::value& value) {
|
||||
using dv::value_type;
|
||||
|
||||
switch (value.getType()) {
|
||||
case value_type::integer:
|
||||
setting->set(value.asInteger());
|
||||
break;
|
||||
case value_type::number:
|
||||
setting->set(value.asNumber());
|
||||
break;
|
||||
case value_type::boolean:
|
||||
setting->set(value.asBoolean());
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("type error, numeric value expected");
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsHandler::setValue(
|
||||
const std::string& name, const dynamic::Value& value
|
||||
const std::string& name, const dv::value& value
|
||||
) {
|
||||
auto found = map.find(name);
|
||||
if (found == map.end()) {
|
||||
@@ -148,16 +155,23 @@ void SettingsHandler::setValue(
|
||||
} else if (auto flag = dynamic_cast<FlagSetting*>(setting)) {
|
||||
set_numeric_value(flag, value);
|
||||
} else if (auto string = dynamic_cast<StringSetting*>(setting)) {
|
||||
if (auto num = std::get_if<integer_t>(&value)) {
|
||||
string->set(std::to_string(*num));
|
||||
} else if (auto num = std::get_if<number_t>(&value)) {
|
||||
string->set(std::to_string(*num));
|
||||
} else if (auto flag = std::get_if<bool>(&value)) {
|
||||
string->set(*flag ? "true" : "false");
|
||||
} else if (auto str = std::get_if<std::string>(&value)) {
|
||||
string->set(*str);
|
||||
} else {
|
||||
throw std::runtime_error("not implemented for type");
|
||||
using dv::value_type;
|
||||
|
||||
switch (value.getType()) {
|
||||
case value_type::integer:
|
||||
string->set(std::to_string(value.asInteger()));
|
||||
break;
|
||||
case value_type::number:
|
||||
string->set(std::to_string(value.asNumber()));
|
||||
break;
|
||||
case value_type::boolean:
|
||||
string->set(value.asBoolean() ? "true" : "false");
|
||||
break;
|
||||
case value_type::string:
|
||||
string->set(value.asString());
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("not implemented for type");
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error(
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "data/dynamic.hpp"
|
||||
#include "data/dv.hpp"
|
||||
|
||||
class Setting;
|
||||
struct EngineSettings;
|
||||
@@ -21,8 +21,8 @@ class SettingsHandler {
|
||||
public:
|
||||
SettingsHandler(EngineSettings& settings);
|
||||
|
||||
dynamic::Value getValue(const std::string& name) const;
|
||||
void setValue(const std::string& name, const dynamic::Value& value);
|
||||
dv::value getValue(const std::string& name) const;
|
||||
void setValue(const std::string& name, const dv::value& value);
|
||||
std::string toString(const std::string& name) const;
|
||||
Setting* getSetting(const std::string& name) const;
|
||||
bool has(const std::string& name) const;
|
||||
|
||||
Reference in New Issue
Block a user