diff options
author | Elias Fleckenstein <eliasfleckenstein@web.de> | 2022-05-17 22:12:00 +0200 |
---|---|---|
committer | Elias Fleckenstein <eliasfleckenstein@web.de> | 2022-05-17 22:12:00 +0200 |
commit | 21df26984da91143c15587f5a03c98d68c3adc4e (patch) | |
tree | aaa707a628ad331f67890023dffe1b4f60dd01d3 /src/database/database-files.cpp | |
parent | b09fc5de5cdb021f43ad32b7e3f50dc75c0bc622 (diff) | |
parent | eabf05758e3ba5f6f4bb1b8d1d1f02179b84e410 (diff) | |
download | dragonfireclient-21df26984da91143c15587f5a03c98d68c3adc4e.tar.xz |
Merge branch 'master' of https://github.com/minetest/minetest
Diffstat (limited to 'src/database/database-files.cpp')
-rw-r--r-- | src/database/database-files.cpp | 125 |
1 files changed, 124 insertions, 1 deletions
diff --git a/src/database/database-files.cpp b/src/database/database-files.cpp index d9d113b4e..7c0dbac28 100644 --- a/src/database/database-files.cpp +++ b/src/database/database-files.cpp @@ -18,7 +18,6 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include <cassert> -#include <json/json.h> #include "convert_json.h" #include "database-files.h" #include "remoteplayer.h" @@ -376,3 +375,127 @@ bool AuthDatabaseFiles::writeAuthFile() } return true; } + +ModMetadataDatabaseFiles::ModMetadataDatabaseFiles(const std::string &savedir): + m_storage_dir(savedir + DIR_DELIM + "mod_storage") +{ +} + +bool ModMetadataDatabaseFiles::getModEntries(const std::string &modname, StringMap *storage) +{ + Json::Value *meta = getOrCreateJson(modname); + if (!meta) + return false; + + const Json::Value::Members attr_list = meta->getMemberNames(); + for (const auto &it : attr_list) { + Json::Value attr_value = (*meta)[it]; + (*storage)[it] = attr_value.asString(); + } + + return true; +} + +bool ModMetadataDatabaseFiles::setModEntry(const std::string &modname, + const std::string &key, const std::string &value) +{ + Json::Value *meta = getOrCreateJson(modname); + if (!meta) + return false; + + (*meta)[key] = Json::Value(value); + m_modified.insert(modname); + + return true; +} + +bool ModMetadataDatabaseFiles::removeModEntry(const std::string &modname, + const std::string &key) +{ + Json::Value *meta = getOrCreateJson(modname); + if (!meta) + return false; + + Json::Value removed; + if (meta->removeMember(key, &removed)) { + m_modified.insert(modname); + return true; + } + return false; +} + +void ModMetadataDatabaseFiles::beginSave() +{ +} + +void ModMetadataDatabaseFiles::endSave() +{ + if (m_modified.empty()) + return; + + if (!fs::CreateAllDirs(m_storage_dir)) { + errorstream << "ModMetadataDatabaseFiles: Unable to save. '" + << m_storage_dir << "' cannot be created." << std::endl; + return; + } + if (!fs::IsDir(m_storage_dir)) { + errorstream << "ModMetadataDatabaseFiles: Unable to save. '" + << m_storage_dir << "' is not a directory." << std::endl; + return; + } + + for (auto it = m_modified.begin(); it != m_modified.end();) { + const std::string &modname = *it; + + const Json::Value &json = m_mod_meta[modname]; + + if (!fs::safeWriteToFile(m_storage_dir + DIR_DELIM + modname, fastWriteJson(json))) { + errorstream << "ModMetadataDatabaseFiles[" << modname + << "]: failed to write file." << std::endl; + ++it; + continue; + } + + it = m_modified.erase(it); + } +} + +void ModMetadataDatabaseFiles::listMods(std::vector<std::string> *res) +{ + // List in-memory metadata first. + for (const auto &pair : m_mod_meta) { + res->push_back(pair.first); + } + + // List other metadata present in the filesystem. + for (const auto &entry : fs::GetDirListing(m_storage_dir)) { + if (!entry.dir && m_mod_meta.count(entry.name) == 0) + res->push_back(entry.name); + } +} + +Json::Value *ModMetadataDatabaseFiles::getOrCreateJson(const std::string &modname) +{ + auto found = m_mod_meta.find(modname); + if (found != m_mod_meta.end()) + return &found->second; + + Json::Value meta(Json::objectValue); + + std::string path = m_storage_dir + DIR_DELIM + modname; + if (fs::PathExists(path)) { + std::ifstream is(path.c_str(), std::ios_base::binary); + + Json::CharReaderBuilder builder; + builder.settings_["collectComments"] = false; + std::string errs; + + if (!Json::parseFromStream(builder, is, &meta, &errs)) { + errorstream << "ModMetadataDatabaseFiles[" << modname + << "]: failed to decode data: " << errs << std::endl; + return nullptr; + } + } + + return &(m_mod_meta[modname] = meta); +} |