Add (optional) client-side saving of server map to disk
authorsfan5 <sfan5@live.de>
Thu, 9 Oct 2014 12:02:02 +0000 (14:02 +0200)
committersfan5 <sfan5@live.de>
Wed, 19 Nov 2014 14:11:23 +0000 (15:11 +0100)
minetest.conf.example
src/client.cpp
src/client.h
src/defaultsettings.cpp

index 345a52bcd1c3558db9b4ea543df026dfed76d748..6bd2e00b4d0dd8eeb2e489effc3df64e71861338 100644 (file)
 #selectionbox_width = 2
 # maximum percentage of current window to be used for hotbar
 #hud_hotbar_max_width = 1.0
+# Save the map received by the client on disk
+#enable_local_map_saving = false
 # Enable highlighting for nodes (disables selectionboxes)
 #enable_node_highlighting = false
 # Texture filtering settings
index 89bb053aeac4ef9ce483e2a5817620918d124a0c..c1806df9961ccfdb79dce105feb7c16c78cbfbf3 100644 (file)
@@ -52,6 +52,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "config.h"
 #include "version.h"
 #include "drawscene.h"
+#include "subgame.h"
+#include "server.h"
+#include "database.h"
+#include "database-sqlite3.h"
 
 extern gui::IGUIEnvironment* guienv;
 
@@ -275,12 +279,43 @@ Client::Client(
 
                m_env.addPlayer(player);
        }
+
+       if (g_settings->getBool("enable_local_map_saving")) {
+               const std::string world_path = porting::path_user + DIR_DELIM + "worlds"
+                               + DIR_DELIM + "server_" + g_settings->get("address")
+                               + "_" + g_settings->get("remote_port");
+
+               SubgameSpec gamespec;
+               if (!getWorldExists(world_path)) {
+                       gamespec = findSubgame(g_settings->get("default_game"));
+                       if (!gamespec.isValid())
+                               gamespec = findSubgame("minimal");
+               } else {
+                       std::string world_gameid = getWorldGameId(world_path, false);
+                       gamespec = findWorldSubgame(world_path);
+               }
+               if (!gamespec.isValid()) {
+                       errorstream << "Couldn't find subgame for local map saving." << std::endl;
+                       return;
+               }
+
+               localserver = new Server(world_path, gamespec, false, false);
+               localdb = new Database_SQLite3(&(ServerMap&)localserver->getMap(), world_path);
+               localdb->beginSave();
+               actionstream << "Local map saving started, map will be saved at '" << world_path << "'" << std::endl;
+       } else {
+               localdb = NULL;
+       }
 }
 
 void Client::Stop()
 {
        //request all client managed threads to stop
        m_mesh_update_thread.Stop();
+       if (localdb != NULL) {
+               actionstream << "Local map saving ended" << std::endl;
+               localdb->endSave();
+       }
 }
 
 bool Client::isShutdown()
@@ -1156,6 +1191,10 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                        sector->insertBlock(block);
                }
 
+               if (localdb != NULL) {
+                       ((ServerMap&) localserver->getMap()).saveBlock(block, localdb);
+               }
+
                /*
                        Add it to mesh update queue and set it to be acknowledged after update.
                */
index 084f7be2c42f465ad298aabf71ccbf32f575623d..e41410f14a25f49e8c0ff6ae1efccd2f7867c853 100644 (file)
@@ -46,6 +46,8 @@ class ClientMediaDownloader;
 struct MapDrawControl;
 class MtEventManager;
 struct PointedThing;
+class Database;
+class Server;
 
 struct QueuedMeshUpdate
 {
@@ -555,6 +557,10 @@ private:
 
        // own state
        LocalClientState m_state;
+
+       // Used for saving server map to disk client-side
+       Database *localdb;
+       Server *localserver;
 };
 
 #endif // !CLIENT_HEADER
index 32a920ed35ce321b44096d98b7f2461e76a372ba..4f297c0993c15f8b04004a408f7e068fc9f7b599 100644 (file)
@@ -131,6 +131,7 @@ void set_default_settings(Settings *settings)
        settings->setDefault("desynchronize_mapblock_texture_animation", "true");
        settings->setDefault("selectionbox_width","2");
        settings->setDefault("hud_hotbar_max_width","1.0");
+       settings->setDefault("enable_local_map_saving", "false");
 
        settings->setDefault("mip_map", "false");
        settings->setDefault("anisotropic_filter", "false");