aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJude Melton-Houghton <jwmhjwmh@gmail.com>2022-01-27 16:24:30 -0500
committerGitHub <noreply@github.com>2022-01-27 22:24:30 +0100
commitfc161e757c14a0d0b86e69fb5ec631fae8b448de (patch)
treed9fc31818916ab8f40238420e1e672fea5e121d9
parent47735c273c96e582f6e9bceee223270ad2a99236 (diff)
downloadhax-minetest-server-fc161e757c14a0d0b86e69fb5ec631fae8b448de.tar.gz
hax-minetest-server-fc161e757c14a0d0b86e69fb5ec631fae8b448de.zip
Automatically migrate client mod storage (#11960)
-rw-r--r--src/client/client.cpp28
-rw-r--r--src/client/client.h3
-rw-r--r--src/client/game.cpp17
3 files changed, 43 insertions, 5 deletions
diff --git a/src/client/client.cpp b/src/client/client.cpp
index d4c271bab..935a82653 100644
--- a/src/client/client.cpp
+++ b/src/client/client.cpp
@@ -50,6 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clientmap.h"
#include "clientmedia.h"
#include "version.h"
+#include "database/database-files.h"
#include "database/database-sqlite3.h"
#include "serialization.h"
#include "guiscalingfilter.h"
@@ -140,6 +141,33 @@ Client::Client(
m_cache_save_interval = g_settings->getU16("server_map_save_interval");
}
+void Client::migrateModStorage()
+{
+ std::string mod_storage_dir = porting::path_user + DIR_DELIM + "client";
+ std::string old_mod_storage = mod_storage_dir + DIR_DELIM + "mod_storage";
+ if (fs::IsDir(old_mod_storage)) {
+ infostream << "Migrating client mod storage to SQLite3 database" << std::endl;
+ {
+ ModMetadataDatabaseFiles files_db(mod_storage_dir);
+ std::vector<std::string> mod_list;
+ files_db.listMods(&mod_list);
+ for (const std::string &modname : mod_list) {
+ infostream << "Migrating client mod storage for mod " << modname << std::endl;
+ StringMap meta;
+ files_db.getModEntries(modname, &meta);
+ for (const auto &pair : meta) {
+ m_mod_storage_database->setModEntry(modname, pair.first, pair.second);
+ }
+ }
+ }
+ if (!fs::Rename(old_mod_storage, old_mod_storage + ".bak")) {
+ // Execution cannot move forward if the migration does not complete.
+ throw BaseException("Could not finish migrating client mod storage");
+ }
+ infostream << "Finished migration of client mod storage" << std::endl;
+ }
+}
+
void Client::loadMods()
{
// Don't load mods twice.
diff --git a/src/client/client.h b/src/client/client.h
index 694cd7d1b..84c85471d 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -385,6 +385,9 @@ public:
bool registerModStorage(ModMetadata *meta) override;
void unregisterModStorage(const std::string &name) override;
+ // Migrates away old files-based mod storage if necessary
+ void migrateModStorage();
+
// The following set of functions is used by ClientMediaDownloader
// Insert a media file appropriately into the appropriate manager
bool loadMedia(const std::string &data, const std::string &filename,
diff --git a/src/client/game.cpp b/src/client/game.cpp
index b6052390b..7478e225f 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -1466,11 +1466,18 @@ bool Game::connectToServer(const GameStartData &start_data,
return false;
}
- client = new Client(start_data.name.c_str(),
- start_data.password, start_data.address,
- *draw_control, texture_src, shader_src,
- itemdef_manager, nodedef_manager, sound, eventmgr,
- m_rendering_engine, connect_address.isIPv6(), m_game_ui.get());
+ try {
+ client = new Client(start_data.name.c_str(),
+ start_data.password, start_data.address,
+ *draw_control, texture_src, shader_src,
+ itemdef_manager, nodedef_manager, sound, eventmgr,
+ m_rendering_engine, connect_address.isIPv6(), m_game_ui.get());
+ client->migrateModStorage();
+ } catch (const BaseException &e) {
+ *error_message = fmtgettext("Error creating client: %s", e.what());
+ errorstream << *error_message << std::endl;
+ return false;
+ }
client->m_simple_singleplayer_mode = simple_singleplayer_mode;