From 0e1f448b619de6651205692806c6f137f481dc43 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 2 Jan 2012 13:31:50 +0200 Subject: Texture cache on client (mostly made by sapier) (breaks network compatibility) --- src/client.cpp | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) (limited to 'src/client.cpp') diff --git a/src/client.cpp b/src/client.cpp index cfdc713db..e3b250b32 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -36,6 +36,22 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tooldef.h" #include "craftitemdef.h" #include +#include "sha1.h" +#include "base64.h" + +static std::string getTextureCacheDir() +{ + return porting::path_userdata + DIR_DELIM + "cache" + DIR_DELIM + "texture"; +} + +struct TextureRequest +{ + std::string name; + + TextureRequest(const std::string &name_=""): + name(name_) + {} +}; /* QueuedMeshUpdate @@ -1232,6 +1248,157 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) event.deathscreen.camera_point_target_z = camera_point_target.Z; m_client_event_queue.push_back(event); } + else if(command == TOCLIENT_ANNOUNCE_TEXTURES) + { + 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.setRun(false); + // Process the remaining TextureSource queue to let MeshUpdateThread + // get it's remaining textures and thus let it stop + while(m_mesh_update_thread.IsRunning()){ + m_tsrc->processQueue(); + } + + int num_textures = readU16(is); + + core::list texture_requests; + + for(int i=0; i data_rw(tmp_os.str().c_str(), tmp_os.str().size()); + + // Create an irrlicht memory file + io::IReadFile *rfile = irrfs->createMemoryReadFile( + *data_rw, tmp_os.str().size(), "_tempreadfile"); + assert(rfile); + // Read image + video::IImage *img = vdrv->createImageFromFile(rfile); + if(!img){ + infostream<<"Client: Cannot create image from data of " + <<"received texture \""<drop(); + } + else { + m_tsrc->insertSourceImage(name, img); + img->drop(); + rfile->drop(); + + texture_found = true; + } + } + else { + infostream<<"Client::Texture cached sha1 hash not matching server hash: " + <"< "<::Iterator i = texture_requests.begin(); + i != texture_requests.end(); i++) { + os<name); + } + + // Make data buffer + std::string s = os.str(); + SharedBuffer data((u8*)s.c_str(), s.size()); + // Send as reliable + Send(0, data, true); + infostream<<"Client: Sending request list to server " <getFileSystem(); @@ -1286,6 +1453,20 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) rfile->drop(); continue; } + + fs::CreateAllDirs(getTextureCacheDir()); + + std::string filename = getTextureCacheDir() + DIR_DELIM + name; + std::ofstream outfile(filename.c_str(), std::ios_base::binary | std::ios_base::trunc); + + if (outfile.good()) { + outfile.write(data.c_str(),data.length()); + outfile.close(); + } + else { + errorstream<<"Client: Unable to open cached texture file "<< filename <insertSourceImage(name, img); img->drop(); rfile->drop(); -- cgit v1.2.3