]> git.lizzy.rs Git - minetest.git/blobdiff - src/client.cpp
Do not allow the m_transforming_liquid queue to increase until all RAM is consumed
[minetest.git] / src / client.cpp
index 89bb053aeac4ef9ce483e2a5817620918d124a0c..b401eb8045b3527df74407b1121012cc45998019 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;
 
@@ -215,6 +219,7 @@ Client::Client(
                IrrlichtDevice *device,
                const char *playername,
                std::string password,
+               bool is_simple_singleplayer_game,
                MapDrawControl &control,
                IWritableTextureSource *tsrc,
                IWritableShaderSource *shsrc,
@@ -250,10 +255,11 @@ Client::Client(
        m_inventory_updated(false),
        m_inventory_from_server(NULL),
        m_inventory_from_server_age(0.0),
-       m_show_hud(true),
+       m_show_highlighted(false),
        m_animation_time(0),
        m_crack_level(-1),
        m_crack_pos(0,0,0),
+       m_highlighted_pos(0,0,0),
        m_map_seed(0),
        m_password(password),
        m_access_denied(false),
@@ -275,12 +281,46 @@ Client::Client(
 
                m_env.addPlayer(player);
        }
+
+       if (g_settings->getBool("enable_local_map_saving")
+                       && !is_simple_singleplayer_game) {
+               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;
+       }
+
+       m_cache_smooth_lighting = g_settings->getBool("smooth_lighting");
 }
 
 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()
@@ -537,7 +577,7 @@ void Client::step(float dtime)
                {
                        if(sendlist.size() == 255 || i == deleted_blocks.end())
                        {
-                               if(sendlist.size() == 0)
+                               if(sendlist.empty())
                                        break;
                                /*
                                        [0] u16 command
@@ -773,7 +813,7 @@ void Client::step(float dtime)
                        }
                }
                // Sync to server
-               if(removed_server_ids.size() != 0)
+               if(!removed_server_ids.empty())
                {
                        std::ostringstream os(std::ios_base::binary);
                        writeU16(os, TOSERVER_REMOVED_SOUNDS);
@@ -1156,6 +1196,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.
                */
@@ -2304,10 +2348,8 @@ void Client::removeNode(v3s16 p)
                        i = modified_blocks.begin();
                        i != modified_blocks.end(); ++i)
        {
-               addUpdateMeshTask(i->first, false, false);
+               addUpdateMeshTaskWithEdge(i->first, false, true);
        }
-       // add urgent task to update the modified node
-       addUpdateMeshTaskForNode(p, false, true);
 }
 
 void Client::addNode(v3s16 p, MapNode n, bool remove_metadata)
@@ -2328,7 +2370,7 @@ void Client::addNode(v3s16 p, MapNode n, bool remove_metadata)
                        i = modified_blocks.begin();
                        i != modified_blocks.end(); ++i)
        {
-               addUpdateMeshTask(i->first, false, false);
+               addUpdateMeshTaskWithEdge(i->first, false, true);
        }
 }
        
@@ -2474,9 +2516,9 @@ int Client::getCrackLevel()
        return m_crack_level;
 }
 
-void Client::setHighlighted(v3s16 pos, bool show_hud)
+void Client::setHighlighted(v3s16 pos, bool show_highlighted)
 {
-       m_show_hud = show_hud;
+       m_show_highlighted = show_highlighted;
        v3s16 old_highlighted_pos = m_highlighted_pos;
        m_highlighted_pos = pos;
        addUpdateMeshTaskForNode(old_highlighted_pos, false, true);
@@ -2566,8 +2608,8 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent)
                // Debug: 1-6ms, avg=2ms
                data->fill(b);
                data->setCrack(m_crack_level, m_crack_pos);
-               data->setHighlighted(m_highlighted_pos, m_show_hud);
-               data->setSmoothLighting(g_settings->getBool("smooth_lighting"));
+               data->setHighlighted(m_highlighted_pos, m_show_highlighted);
+               data->setSmoothLighting(m_cache_smooth_lighting);
        }
 
        // Add task to queue
@@ -2577,9 +2619,7 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent)
 void Client::addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server, bool urgent)
 {
        try{
-               v3s16 p = blockpos + v3s16(0,0,0);
-               //MapBlock *b = m_env.getMap().getBlockNoCreate(p);
-               addUpdateMeshTask(p, ack_to_server, urgent);
+               addUpdateMeshTask(blockpos, ack_to_server, urgent);
        }
        catch(InvalidPositionException &e){}
 
@@ -2607,8 +2647,7 @@ void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool ur
        v3s16 blockpos_relative = blockpos * MAP_BLOCKSIZE;
 
        try{
-               v3s16 p = blockpos + v3s16(0,0,0);
-               addUpdateMeshTask(p, ack_to_server, urgent);
+               addUpdateMeshTask(blockpos, ack_to_server, urgent);
        }
        catch(InvalidPositionException &e){}
 
@@ -2685,7 +2724,7 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
        {
                verbosestream<<"Updating item textures and meshes"<<std::endl;
                wchar_t* text = wgettext("Item textures...");
-               draw_load_screen(text, device, guienv, font, 0, 0);
+               draw_load_screen(text, device, guienv, 0, 0);
                std::set<std::string> names = m_itemdef->getAll();
                size_t size = names.size();
                size_t count = 0;
@@ -2698,7 +2737,7 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
                        count++;
                        percent = count*100/size;
                        if (count%50 == 0) // only update every 50 item
-                               draw_load_screen(text, device, guienv, font, 0, percent);
+                               draw_load_screen(text, device, guienv, 0, percent);
                }
                delete[] text;
        }
@@ -2734,7 +2773,7 @@ void Client::makeScreenshot(IrrlichtDevice *device)
        irr::video::IVideoDriver *driver = device->getVideoDriver();
        irr::video::IImage* const raw_image = driver->createScreenShot();
        if (raw_image) {
-               irr::video::IImage* const image = driver->createImage(video::ECF_R8G8B8, 
+               irr::video::IImage* const image = driver->createImage(video::ECF_R8G8B8,
                        raw_image->getDimension());
 
                if (image) {
@@ -2743,14 +2782,14 @@ void Client::makeScreenshot(IrrlichtDevice *device)
                        snprintf(filename, sizeof(filename), "%s" DIR_DELIM "screenshot_%u.png",
                                 g_settings->get("screenshot_path").c_str(),
                                 device->getTimer()->getRealTime());
-                       std::stringstream sstr;
+                       std::ostringstream sstr;
                        if (driver->writeImageToFile(image, filename)) {
                                sstr << "Saved screenshot to '" << filename << "'";
                        } else {
                                sstr << "Failed to save screenshot '" << filename << "'";
                        }
                        m_chat_queue.push_back(narrow_to_wide(sstr.str()));
-                       infostream << sstr << std::endl;
+                       infostream << sstr.str() << std::endl;
                        image->drop();
                }
                raw_image->drop();