+ // Mesh update thread must be stopped while
+ // updating content definitions
+ assert(!m_mesh_update_thread.IsRunning());
+
+ int num_textures = readU16(is);
+
+ core::list<TextureRequest> texture_requests;
+
+ for(int i=0; i<num_textures; i++){
+
+ bool texture_found = false;
+
+ //read texture from cache
+ std::string name = deSerializeString(is);
+ std::string sha1_texture = deSerializeString(is);
+
+ // if name contains illegal characters, ignore the texture
+ if(!string_allowed(name, TEXTURENAME_ALLOWED_CHARS)){
+ errorstream<<"Client: ignoring illegal texture name "
+ <<"sent by server: \""<<name<<"\""<<std::endl;
+ continue;
+ }
+
+ std::string tpath = getTextureCacheDir() + DIR_DELIM + name;
+ // Read data
+ std::ifstream fis(tpath.c_str(), std::ios_base::binary);
+
+
+ if(fis.good() == false){
+ infostream<<"Client::Texture not found in cache: "
+ <<name << " expected it at: "<<tpath<<std::endl;
+ }
+ else
+ {
+ std::ostringstream tmp_os(std::ios_base::binary);
+ bool bad = false;
+ for(;;){
+ char buf[1024];
+ fis.read(buf, 1024);
+ std::streamsize len = fis.gcount();
+ tmp_os.write(buf, len);
+ if(fis.eof())
+ break;
+ if(!fis.good()){
+ bad = true;
+ break;
+ }
+ }
+ if(bad){
+ infostream<<"Client: Failed to read texture from cache\""
+ <<name<<"\""<<std::endl;
+ }
+ else {
+
+ SHA1 sha1;
+ sha1.addBytes(tmp_os.str().c_str(), tmp_os.str().length());
+
+ unsigned char *digest = sha1.getDigest();
+
+ std::string digest_string = base64_encode(digest, 20);
+
+ if (digest_string == sha1_texture) {
+ // Silly irrlicht's const-incorrectness
+ Buffer<char> 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 \""<<name<<"\""<<std::endl;
+ rfile->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: "
+ <<name << ": server ->"<<sha1_texture <<" client -> "<<digest_string<<std::endl;
+ }
+
+ free(digest);
+ }
+ }
+
+ //add texture request
+ if (!texture_found) {
+ infostream<<"Client: Adding texture to request list: \""
+ <<name<<"\""<<std::endl;
+ texture_requests.push_back(TextureRequest(name));
+ }
+