summaryrefslogtreecommitdiff
path: root/src/database/database-files.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/database/database-files.cpp')
-rw-r--r--src/database/database-files.cpp136
1 files changed, 135 insertions, 1 deletions
diff --git a/src/database/database-files.cpp b/src/database/database-files.cpp
index d9d113b4e..9021ae61b 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,138 @@ 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 (!fs::CreateAllDirs(m_storage_dir)) {
+ errorstream << "ModMetadataDatabaseFiles: Unable to save. '" << m_storage_dir
+ << "' tree cannot be created." << std::endl;
+ return;
+ }
+
+ for (auto it = m_modified.begin(); it != m_modified.end();) {
+ const std::string &modname = *it;
+
+ if (!fs::PathExists(m_storage_dir)) {
+ if (!fs::CreateAllDirs(m_storage_dir)) {
+ errorstream << "ModMetadataDatabaseFiles[" << modname
+ << "]: Unable to save. '" << m_storage_dir
+ << "' tree cannot be created." << std::endl;
+ ++it;
+ continue;
+ }
+ } else if (!fs::IsDir(m_storage_dir)) {
+ errorstream << "ModMetadataDatabaseFiles[" << modname << "]: Unable to save. '"
+ << m_storage_dir << "' is not a directory." << std::endl;
+ ++it;
+ continue;
+ }
+
+ const Json::Value &json = m_mod_meta[modname];
+
+ if (!fs::safeWriteToFile(m_storage_dir + DIR_DELIM + modname, fastWriteJson(json))) {
+ errorstream << "ModMetadataDatabaseFiles[" << modname
+ << "]: failed 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()) {
+ fs::CreateAllDirs(m_storage_dir);
+
+ 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 read data (Json decoding failure). Message: "
+ << errs << std::endl;
+ return nullptr;
+ }
+ }
+
+ return &(m_mod_meta[modname] = meta);
+ } else {
+ return &found->second;
+ }
+}