diff --git a/src/client.cpp b/src/client.cpp index 56555804..6da26abf 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -40,6 +40,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "clientmap.h" #include "filecache.h" #include "sound.h" +#include "utility_string.h" +#include "hex.h" static std::string getMediaCacheDir() { @@ -795,6 +797,66 @@ void Client::step(float dtime) } } +bool Client::loadMedia(const std::string &data, const std::string &filename) +{ + // Silly irrlicht's const-incorrectness + Buffer 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 \""<getFileSystem(); + video::IVideoDriver *vdrv = m_device->getVideoDriver(); + + // Create an irrlicht memory file + io::IReadFile *rfile = irrfs->createMemoryReadFile( + *data_rw, data_rw.getSize(), "_tempreadfile"); + assert(rfile); + // Read image + video::IImage *img = vdrv->createImageFromFile(rfile); + if(!img){ + errorstream<<"Client: Cannot create image from data of " + <<"file \""<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 \""<loadSoundData(name, data); + return true; + } + + errorstream<<"Client: Don't know how to load file \"" + <getFileSystem(); - video::IVideoDriver *vdrv = m_device->getVideoDriver(); - std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); @@ -1410,13 +1469,11 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) core::list file_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 file \""<drop(); - } - else { - m_tsrc->insertSourceImage(name, img); - img->drop(); - rfile->drop(); - - file_found = true; - } + bool success = loadMedia(tmp_os.str(), name); + if(success){ + verbosestream<<"Client: Loaded cached media: " + <"< "<::Iterator i = file_requests.begin(); i != file_requests.end(); i++) { @@ -1521,11 +1538,6 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) } else if(command == TOCLIENT_MEDIA) { - verbosestream<<"Client received TOCLIENT_MEDIA"<getFileSystem(); - video::IVideoDriver *vdrv = m_device->getVideoDriver(); - std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); @@ -1547,7 +1559,10 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) */ int num_bunches = readU16(is); int bunch_i = readU16(is); - m_media_receive_progress = (float)bunch_i / (float)(num_bunches - 1); + if(num_bunches >= 2) + m_media_receive_progress = (float)bunch_i / (float)(num_bunches - 1); + else + m_media_receive_progress = 1.0; if(bunch_i == num_bunches - 1) m_media_received = true; int num_files = readU32(is); @@ -1564,19 +1579,14 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) <<"sent by server: \""< 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 file \""<drop(); + + bool success = loadMedia(data, name); + if(success){ + verbosestream<<"Client: Loaded received media: " + <<"\""<getValue(), data); + m_media_cache.update_sha1(data); } - - m_tsrc->insertSourceImage(name, img); - img->drop(); - rfile->drop(); } ClientEvent event; diff --git a/src/client.h b/src/client.h index b15dbed5..302dd800 100644 --- a/src/client.h +++ b/src/client.h @@ -315,6 +315,9 @@ public: private: + // Insert a media file appropriately into the appropriate manager + bool loadMedia(const std::string &data, const std::string &filename); + // Virtual methods from con::PeerHandler void peerAdded(con::Peer *peer); void deletingPeer(con::Peer *peer, bool timeout); diff --git a/src/filecache.cpp b/src/filecache.cpp index 5ba8ef5c..0ef2dd11 100644 --- a/src/filecache.cpp +++ b/src/filecache.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "utility.h" #include "hex.h" +#include "sha1.h" #include #include @@ -34,7 +35,7 @@ bool FileCache::loadByPath(const std::string &path, std::ostream &os) if(!fis.good()){ verbosestream<<"FileCache: File not found in cache: " - < &dst_paths, - std::set > &dst_datas) + std::set &dst_datas) { if(m_fetched.count(name)) return; diff --git a/src/server.cpp b/src/server.cpp index 13a8ebf7..02734bbc 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -51,6 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "utility_string.h" #include "sound.h" // dummySoundManager #include "event_manager.h" +#include "hex.h" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" @@ -3996,14 +3997,13 @@ void Server::fillMediaCache() sha1.addBytes(tmp_os.str().c_str(), tmp_os.str().length()); unsigned char *digest = sha1.getDigest(); - std::string digest_string = base64_encode(digest, 20); - + std::string sha1_base64 = base64_encode(digest, 20); + std::string sha1_hex = hex_encode((char*)digest, 20); free(digest); // Put in list - this->m_media[filename] = MediaInfo(filepath, digest_string); - verbosestream<<"Server: sha1 for "<m_media[filename] = MediaInfo(filepath, sha1_base64); + verbosestream<<"Server: "< -#include #include class OnDemandSoundFetcher @@ -30,7 +29,7 @@ class OnDemandSoundFetcher public: virtual void fetchSounds(const std::string &name, std::set &dst_paths, - std::set > &dst_datas) = 0; + std::set &dst_datas) = 0; }; struct SimpleSoundSpec @@ -53,10 +52,10 @@ public: // Multiple sounds can be loaded per name; when played, the sound // should be chosen randomly from alternatives // Return value determines success/failure - virtual bool loadSound(const std::string &name, + virtual bool loadSoundFile(const std::string &name, const std::string &filepath) = 0; - virtual bool loadSound(const std::string &name, - const std::vector &filedata) = 0; + virtual bool loadSoundData(const std::string &name, + const std::string &filedata) = 0; virtual void updateListener(v3f pos, v3f vel, v3f at, v3f up) = 0; @@ -79,10 +78,10 @@ public: class DummySoundManager: public ISoundManager { public: - virtual bool loadSound(const std::string &name, + virtual bool loadSoundFile(const std::string &name, const std::string &filepath) {return true;} - virtual bool loadSound(const std::string &name, - const std::vector &filedata) {return true;} + virtual bool loadSoundData(const std::string &name, + const std::string &filedata) {return true;} void updateListener(v3f pos, v3f vel, v3f at, v3f up) {} int playSound(const std::string &name, bool loop, float volume) {return 0;} diff --git a/src/sound_openal.cpp b/src/sound_openal.cpp index 6f9ff3bd..f7bce654 100644 --- a/src/sound_openal.cpp +++ b/src/sound_openal.cpp @@ -286,22 +286,6 @@ public: return bufs[j]; } - bool loadSound(const std::string &name, - const std::string &filepath) - { - SoundBuffer *buf = loadOggFile(filepath); - if(buf) - addBuffer(name, buf); - return false; - } - bool loadSound(const std::string &name, - const std::vector &filedata) - { - errorstream<<"OpenALSoundManager: Loading from filedata not" - " implemented"< paths; - std::set > datas; + std::set datas; m_fetcher->fetchSounds(name, paths, datas); for(std::set::iterator i = paths.begin(); i != paths.end(); i++){ - loadSound(name, *i); + loadSoundFile(name, *i); } - for(std::set >::iterator i = datas.begin(); + for(std::set::iterator i = datas.begin(); i != datas.end(); i++){ - loadSound(name, *i); + loadSoundData(name, *i); } return getBuffer(name); } @@ -439,6 +423,22 @@ public: /* Interface */ + bool loadSoundFile(const std::string &name, + const std::string &filepath) + { + SoundBuffer *buf = loadOggFile(filepath); + if(buf) + addBuffer(name, buf); + return false; + } + bool loadSoundData(const std::string &name, + const std::string &filedata) + { + errorstream<<"OpenALSoundManager: Loading from filedata not" + " implemented"<