Update inventory texture too
[oweals/minetest.git] / src / client.cpp
index 1daeeba36fde0f73130885204d8c5465d3604958..7093a5190a2c40d176bf8279bb1437c2ba9cdba5 100644 (file)
@@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "nodemetadata.h"
 #include "nodedef.h"
 #include "tooldef.h"
+#include <IFileSystem.h>
 
 /*
        QueuedMeshUpdate
@@ -221,16 +222,14 @@ Client::Client(
 
        // Build main texture atlas, now that the GameDef exists (that is, us)
        if(g_settings->getBool("enable_texture_atlas"))
-               tsrc->buildMainAtlas(this);
+               m_tsrc->buildMainAtlas(this);
        else
                infostream<<"Not building texture atlas."<<std::endl;
        
-       // Update textures
-       m_nodedef->updateTextures(tsrc);
+       // Update node textures
+       m_nodedef->updateTextures(m_tsrc);
 
-       // NOTE: This should be done only after getting possible dynamic
-       // game definitions from the server, or at least shut down and
-       // restarted when doing so
+       // Start threads after setting up content definitions
        m_mesh_update_thread.Start();
 
        /*
@@ -1523,6 +1522,73 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                m_mesh_update_thread.setRun(true);
                m_mesh_update_thread.Start();
        }
+       else if(command == TOCLIENT_TEXTURES)
+       {
+               infostream<<"Client: Received textures: packet size: "<<datasize
+                               <<std::endl;
+
+               io::IFileSystem *irrfs = m_device->getFileSystem();
+               video::IVideoDriver *vdrv = m_device->getVideoDriver();
+
+               std::string datastring((char*)&data[2], datasize-2);
+               std::istringstream is(datastring, std::ios_base::binary);
+
+               // Stop threads while updating content definitions
+               m_mesh_update_thread.stop();
+               
+               /*
+                       u16 command
+                       u32 number of textures
+                       for each texture {
+                               u16 length of name
+                               string name
+                               u32 length of data
+                               data
+                       }
+               */
+               int num_textures = readU32(is);
+               infostream<<"Client: Received textures: count: "<<num_textures
+                               <<std::endl;
+               for(int i=0; i<num_textures; i++){
+                       std::string name = deSerializeString(is);
+                       std::string data = deSerializeLongString(is);
+                       // Silly irrlicht's const-incorrectness
+                       Buffer<char> data_rw(data.c_str(), data.size());
+                       // Create an irrlicht memory file
+                       io::IReadFile *rfile = irrfs->createMemoryReadFile(
+                                       *data_rw, data.size(), "_tempreadfile");
+                       assert(rfile);
+                       // Read image
+                       video::IImage *img = vdrv->createImageFromFile(rfile);
+                       if(!img){
+                               errorstream<<"Client: Cannot create image from data of "
+                                               <<"received texture \""<<name<<"\""<<std::endl;
+                               rfile->drop();
+                               continue;
+                       }
+                       m_tsrc->insertSourceImage(name, img);
+                       img->drop();
+                       rfile->drop();
+               }
+               
+               // Rebuild inherited images and recreate textures
+               m_tsrc->rebuildImagesAndTextures();
+
+               // Update texture atlas
+               if(g_settings->getBool("enable_texture_atlas"))
+                       m_tsrc->buildMainAtlas(this);
+               
+               // Update node textures
+               m_nodedef->updateTextures(m_tsrc);
+
+               // Resume threads
+               m_mesh_update_thread.setRun(true);
+               m_mesh_update_thread.Start();
+
+               ClientEvent event;
+               event.type = CE_TEXTURES_UPDATED;
+               m_client_event_queue.push_back(event);
+       }
        else
        {
                infostream<<"Client: Ignoring unknown command "