+
+ /*
+ Update positions of sounds attached to objects
+ */
+ {
+ for(std::map<int, u16>::iterator
+ i = m_sounds_to_objects.begin();
+ i != m_sounds_to_objects.end(); ++i)
+ {
+ int client_id = i->first;
+ u16 object_id = i->second;
+ ClientActiveObject *cao = m_env.getActiveObject(object_id);
+ if(!cao)
+ continue;
+ v3f pos = cao->getPosition();
+ m_sound->updateSoundPosition(client_id, pos);
+ }
+ }
+
+ /*
+ Handle removed remotely initiated sounds
+ */
+ m_removed_sounds_check_timer += dtime;
+ if(m_removed_sounds_check_timer >= 2.32) {
+ m_removed_sounds_check_timer = 0;
+ // Find removed sounds and clear references to them
+ std::vector<s32> removed_server_ids;
+ for(std::map<s32, int>::iterator
+ i = m_sounds_server_to_client.begin();
+ i != m_sounds_server_to_client.end();) {
+ s32 server_id = i->first;
+ int client_id = i->second;
+ ++i;
+ if(!m_sound->soundExists(client_id)) {
+ m_sounds_server_to_client.erase(server_id);
+ m_sounds_client_to_server.erase(client_id);
+ m_sounds_to_objects.erase(client_id);
+ removed_server_ids.push_back(server_id);
+ }
+ }
+
+ // Sync to server
+ if(!removed_server_ids.empty()) {
+ sendRemovedSounds(removed_server_ids);
+ }
+ }
+
+ // Write server map
+ if (m_localdb && m_localdb_save_interval.step(dtime,
+ m_cache_save_interval)) {
+ m_localdb->endSave();
+ m_localdb->beginSave();
+ }
+}
+
+bool Client::loadMedia(const std::string &data, const std::string &filename)
+{
+ // Silly irrlicht's const-incorrectness
+ Buffer<char> data_rw(data.c_str(), data.size());
+
+ std::string name;
+
+ const char *image_ext[] = {
+ ".png", ".jpg", ".bmp", ".tga",
+ ".pcx", ".ppm", ".psd", ".wal", ".rgb",
+ NULL
+ };
+ name = removeStringEnd(filename, image_ext);
+ if(name != "")
+ {
+ verbosestream<<"Client: Attempting to load image "
+ <<"file \""<<filename<<"\""<<std::endl;
+
+ io::IFileSystem *irrfs = m_device->getFileSystem();
+ video::IVideoDriver *vdrv = m_device->getVideoDriver();
+
+ // Create an irrlicht memory file
+ io::IReadFile *rfile = irrfs->createMemoryReadFile(
+ *data_rw, data_rw.getSize(), "_tempreadfile");
+
+ FATAL_ERROR_IF(!rfile, "Could not create irrlicht memory file.");
+
+ // Read image
+ video::IImage *img = vdrv->createImageFromFile(rfile);
+ if(!img){
+ errorstream<<"Client: Cannot create image from data of "
+ <<"file \""<<filename<<"\""<<std::endl;
+ rfile->drop();
+ return false;
+ }
+ else {
+ m_tsrc->insertSourceImage(filename, img);
+ img->drop();
+ rfile->drop();
+ return true;
+ }
+ }
+
+ const char *sound_ext[] = {
+ ".0.ogg", ".1.ogg", ".2.ogg", ".3.ogg", ".4.ogg",
+ ".5.ogg", ".6.ogg", ".7.ogg", ".8.ogg", ".9.ogg",
+ ".ogg", NULL
+ };
+ name = removeStringEnd(filename, sound_ext);
+ if(name != "")
+ {
+ verbosestream<<"Client: Attempting to load sound "
+ <<"file \""<<filename<<"\""<<std::endl;
+ m_sound->loadSoundData(name, data);
+ return true;
+ }
+
+ const char *model_ext[] = {
+ ".x", ".b3d", ".md2", ".obj",
+ NULL
+ };
+ name = removeStringEnd(filename, model_ext);
+ if(name != "")
+ {
+ verbosestream<<"Client: Storing model into memory: "
+ <<"\""<<filename<<"\""<<std::endl;
+ if(m_mesh_data.count(filename))
+ errorstream<<"Multiple models with name \""<<filename.c_str()
+ <<"\" found; replacing previous model"<<std::endl;
+ m_mesh_data[filename] = data;
+ return true;
+ }
+
+ errorstream<<"Client: Don't know how to load file \""
+ <<filename<<"\""<<std::endl;
+ return false;