aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp
index fafb3c8ef..c49829592 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -78,6 +78,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serverlist.h"
#include "guiEngine.h"
+#ifdef USE_LEVELDB
+#include "database-sqlite3.h"
+#include "database-leveldb.h"
+#endif
+
/*
Settings.
These are loaded from the config file.
@@ -789,6 +794,10 @@ int main(int argc, char *argv[])
_("Set logfile path ('' = no logging)"))));
allowed_options.insert(std::make_pair("gameid", ValueSpec(VALUETYPE_STRING,
_("Set gameid (\"--gameid list\" prints available ones)"))));
+ #if USE_LEVELDB
+ allowed_options.insert("migrate", ValueSpec(VALUETYPE_STRING,
+ _("Migrate from current map backend to another")));
+ #endif
#ifndef SERVER
allowed_options.insert(std::make_pair("videomodes", ValueSpec(VALUETYPE_FLAG,
_("Show available video modes"))));
@@ -1085,6 +1094,7 @@ int main(int argc, char *argv[])
}
}
+
/*
Run dedicated server if asked to or no other option
*/
@@ -1207,6 +1217,61 @@ int main(int argc, char *argv[])
// Create server
Server server(world_path, gamespec, false);
+
+ #if USE_LEVELDB
+ // Database migration
+ if (cmd_args.exists("migrate")) {
+ std::string migrate_to = cmd_args.get("migrate");
+ Settings world_mt;
+ bool success = world_mt.readConfigFile((world_path + DIR_DELIM + "world.mt").c_str());
+ if (!success) {
+ errorstream << "Cannot read world.mt" << std::endl;
+ return 1;
+ }
+ if (!world_mt.exists("backend")) {
+ errorstream << "Please specify your current backend in world.mt file:"
+ << std::endl << " backend = {sqlite3|leveldb|dummy}" << std::endl;
+ return 1;
+ }
+ std::string backend = world_mt.get("backend");
+ Database *new_db;
+ if (backend == migrate_to) {
+ errorstream << "Cannot migrate: new backend is same as the old one" << std::endl;
+ return 1;
+ }
+ if (migrate_to == "sqlite3")
+ new_db = new Database_SQLite3(&(ServerMap&)server.getMap(), world_path);
+ else if (migrate_to == "leveldb")
+ new_db = new Database_LevelDB(&(ServerMap&)server.getMap(), world_path);
+ else {
+ errorstream << "Migration to " << migrate_to << " is not supported" << std::endl;
+ return 1;
+ }
+
+ core::list<v3s16> blocks;
+ ServerMap &old_map = ((ServerMap&)server.getMap());
+ old_map.listAllLoadableBlocks(blocks);
+ int count = 0;
+ new_db->beginSave();
+ for (core::list<v3s16>::Iterator i = blocks.begin(); i != blocks.end(); ++i) {
+ MapBlock *block = old_map.loadBlock(*i);
+ new_db->saveBlock(block);
+ MapSector *sector = old_map.getSectorNoGenerate(v2s16(i->X, i->Z));
+ sector->deleteBlock(block);
+ ++count;
+ if (count % 500 == 0)
+ actionstream << "Migrated " << count << " blocks "
+ << (100.0 * count / blocks.size()) << "\% completed" << std::endl;
+ }
+ new_db->endSave();
+
+ actionstream << "Successfully migrated " << count << " blocks" << std::endl;
+ actionstream << "Don't forget to update your world.mt backend setting!" << std::endl;
+
+ return 0;
+ }
+ #endif
+
server.start(port);
// Run server