From f801e16b787f033cea4e473d69b54fe65248a439 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sun, 25 Mar 2012 11:50:29 +0300 Subject: [PATCH] Texture cache -> Media cache WIP --- src/client.cpp | 129 ++++++++++++++------------ src/client.h | 17 ++-- src/clientserver.h | 18 ++-- src/filecache.cpp | 43 ++++----- src/filecache.h | 17 +--- src/game.cpp | 9 +- src/server.cpp | 224 +++++++++++++++++++++++---------------------- src/server.h | 19 ++-- 8 files changed, 235 insertions(+), 241 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 3a08b25c2..56555804e 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -41,16 +41,16 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filecache.h" #include "sound.h" -static std::string getTextureCacheDir() +static std::string getMediaCacheDir() { - return porting::path_user + DIR_DELIM + "cache" + DIR_DELIM + "textures"; + return porting::path_user + DIR_DELIM + "cache" + DIR_DELIM + "media"; } -struct TextureRequest +struct MediaRequest { std::string name; - TextureRequest(const std::string &name_=""): + MediaRequest(const std::string &name_=""): name(name_) {} }; @@ -256,9 +256,9 @@ Client::Client( m_map_seed(0), m_password(password), m_access_denied(false), - m_texture_cache(getTextureCacheDir()), - m_texture_receive_progress(0), - m_textures_received(false), + m_media_cache(getMediaCacheDir()), + m_media_receive_progress(0), + m_media_received(false), m_itemdef_received(false), m_nodedef_received(false), m_time_of_day_set(false), @@ -1391,7 +1391,7 @@ 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) + else if(command == TOCLIENT_ANNOUNCE_MEDIA) { io::IFileSystem *irrfs = m_device->getFileSystem(); video::IVideoDriver *vdrv = m_device->getVideoDriver(); @@ -1403,33 +1403,36 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) // updating content definitions assert(!m_mesh_update_thread.IsRunning()); - int num_textures = readU16(is); + int num_files = readU16(is); + + verbosestream<<"Client received TOCLIENT_ANNOUNCE_MEDIA (" + < texture_requests; + core::list file_requests; - for(int i=0; i data_rw(tmp_os.str().c_str(), tmp_os.str().size()); @@ -1449,7 +1452,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) video::IImage *img = vdrv->createImageFromFile(rfile); if(!img){ infostream<<"Client: Cannot create image from data of " - <<"received texture \""<drop(); } else { @@ -1457,22 +1460,22 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) img->drop(); rfile->drop(); - texture_found = true; + file_found = true; } } else { - infostream<<"Client::Texture cached sha1 hash not matching server hash: " - <"< "<"< "<::Iterator i = texture_requests.begin(); - i != texture_requests.end(); i++) { + for(core::list::Iterator i = file_requests.begin(); + i != file_requests.end(); i++) { os<name); } @@ -1513,10 +1516,13 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) SharedBuffer data((u8*)s.c_str(), s.size()); // Send as reliable Send(0, data, true); - infostream<<"Client: Sending request list to server " <getFileSystem(); video::IVideoDriver *vdrv = m_device->getVideoDriver(); @@ -1529,10 +1535,10 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) /* u16 command - u16 total number of texture bunches + u16 total number of file bunches u16 index of this bunch - u32 number of textures in this bunch - for each texture { + u32 number of files in this bunch + for each file { u16 length of name string name u32 length of data @@ -1541,20 +1547,20 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) */ int num_bunches = readU16(is); int bunch_i = readU16(is); - m_texture_receive_progress = (float)bunch_i / (float)(num_bunches - 1); + m_media_receive_progress = (float)bunch_i / (float)(num_bunches - 1); if(bunch_i == num_bunches - 1) - m_textures_received = true; - int num_textures = readU32(is); - infostream<<"Client: Received textures: bunch "<createImageFromFile(rfile); if(!img){ errorstream<<"Client: Cannot create image from data of " - <<"received texture \""<drop(); continue; } - fs::CreateAllDirs(getTextureCacheDir()); + bool did = fs::CreateAllDirs(getMediaCacheDir()); + if(!did){ + errorstream<<"Could not create media cache directory" + <::Node *n; - n = m_texture_name_sha1_map.find(name); + n = m_media_name_sha1_map.find(name); if(n == NULL) - errorstream<<"The server sent a texture that has not been announced." - <getValue()); + m_media_cache.updateByChecksum(n->getValue(), data); } m_tsrc->insertSourceImage(name, img); @@ -2358,11 +2367,11 @@ void Client::afterContentReceived() { assert(m_itemdef_received); assert(m_nodedef_received); - assert(m_textures_received); + assert(m_media_received); // remove the information about which checksum each texture // ought to have - m_texture_name_sha1_map.clear(); + m_media_name_sha1_map.clear(); // Rebuild inherited images and recreate textures m_tsrc->rebuildImagesAndTextures(); diff --git a/src/client.h b/src/client.h index 8d7597e80..b15dbed54 100644 --- a/src/client.h +++ b/src/client.h @@ -290,11 +290,11 @@ public: std::wstring accessDeniedReason() { return m_access_denied_reason; } - float textureReceiveProgress() - { return m_texture_receive_progress; } + float mediaReceiveProgress() + { return m_media_receive_progress; } bool texturesReceived() - { return m_textures_received; } + { return m_media_received; } bool itemdefReceived() { return m_itemdef_received; } bool nodedefReceived() @@ -367,12 +367,11 @@ private: bool m_access_denied; std::wstring m_access_denied_reason; Queue m_client_event_queue; - FileCache m_texture_cache; - // a map of the name and SHA1 checksum of each texture; - // cleared after content has been recieved - core::map m_texture_name_sha1_map; - float m_texture_receive_progress; - bool m_textures_received; + FileCache m_media_cache; + // Mapping from media file name to SHA1 checksum + core::map m_media_name_sha1_map; + float m_media_receive_progress; + bool m_media_received; bool m_itemdef_received; bool m_nodedef_received; friend class FarMesh; diff --git a/src/clientserver.h b/src/clientserver.h index 9cbb7a685..8ac0aa877 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., PROTOCOL_VERSION 3: Base for writing changes here PROTOCOL_VERSION 4: - Add TOCLIENT_TEXTURES + Add TOCLIENT_MEDIA Add TOCLIENT_TOOLDEF Add TOCLIENT_NODEDEF Add TOCLIENT_CRAFTITEMDEF @@ -215,13 +215,13 @@ enum ToClientCommand v3f1000 camera point target (to point the death cause or whatever) */ - TOCLIENT_TEXTURES = 0x38, + TOCLIENT_MEDIA = 0x38, /* u16 command u16 total number of texture bunches u16 index of this bunch - u32 number of textures in this bunch - for each texture { + u32 number of files in this bunch + for each file { u16 length of name string name u32 length of data @@ -250,11 +250,11 @@ enum ToClientCommand serialized CraftiItemDefManager */ - TOCLIENT_ANNOUNCE_TEXTURES = 0x3c, + TOCLIENT_ANNOUNCE_MEDIA = 0x3c, /* u16 command - u32 number of textures + u32 number of files for each texture { u16 length of name string name @@ -468,11 +468,11 @@ enum ToServerCommand s32[len] sound_id */ - TOSERVER_REQUEST_TEXTURES = 0x40, + TOSERVER_REQUEST_MEDIA = 0x40, /* u16 command - u16 number of textures requested - for each texture { + u16 number of files requested + for each file { u16 length of name string name } diff --git a/src/filecache.cpp b/src/filecache.cpp index 28d6bbc80..5ba8ef5cc 100644 --- a/src/filecache.cpp +++ b/src/filecache.cpp @@ -28,14 +28,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include -bool FileCache::loadByPath(const std::string &name, std::ostream &os, - const std::string &path) +bool FileCache::loadByPath(const std::string &path, std::ostream &os) { std::ifstream fis(path.c_str(), std::ios_base::binary); if(!fis.good()){ - infostream<<"FileCache: File not found in cache: " - <updateAliases(m_itemdef); @@ -2183,7 +2183,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) SendNodeDef(m_con, peer_id, m_nodedef); // Send texture announcement - SendTextureAnnouncement(peer_id); + sendMediaAnnouncement(peer_id); // Send player info to all players //SendPlayerInfos(); @@ -2842,29 +2842,28 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) // ActiveObject is added to environment in AsyncRunStep after // the previous addition has been succesfully removed } - else if(command == TOSERVER_REQUEST_TEXTURES) { + else if(command == TOSERVER_REQUEST_MEDIA) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); - - core::list tosend; - u16 numtextures = readU16(is); + core::list tosend; + u16 numfiles = readU16(is); - infostream<<"Sending "<definitions_sent = true; } else if(command == TOSERVER_INTERACT) @@ -3928,32 +3927,32 @@ void Server::SendBlocks(float dtime) } } -void Server::PrepareTextures() +void Server::fillMediaCache() { DSTACK(__FUNCTION_NAME); - infostream<<"Server: Calculating texture checksums"<::Iterator i = m_mods.begin(); i != m_mods.end(); i++){ const ModSpec &mod = *i; - std::string texturepath = mod.path + DIR_DELIM + "textures"; - std::vector dirlist = fs::GetDirListing(texturepath); + std::string filepath = mod.path + DIR_DELIM + "textures"; + std::vector dirlist = fs::GetDirListing(filepath); for(u32 j=0; jm_Textures[tname] = TextureInformation(tpath,digest_string); + this->m_media[tname] = MediaInfo(tpath,digest_string); verbosestream<<"Server: sha1 for "< texture_announcements; - - for (std::map::iterator i = m_Textures.begin();i != m_Textures.end(); i++ ) { + core::list file_announcements; + for(std::map::iterator i = m_media.begin(); + i != m_media.end(); i++){ // Put in list - texture_announcements.push_back( - SendableTextureAnnouncement(i->first, i->second.sha1_digest)); + file_announcements.push_back( + SendableMediaAnnouncement(i->first, i->second.sha1_digest)); } - //send announcements + // Make packet + std::ostringstream os(std::ios_base::binary); /* u16 command - u32 number of textures + u32 number of files for each texture { u16 length of name string name - u16 length of digest string + u16 length of sha1_digest string sha1_digest } */ - std::ostringstream os(std::ios_base::binary); + + writeU16(os, TOCLIENT_ANNOUNCE_MEDIA); + writeU16(os, file_announcements.size()); - writeU16(os, TOCLIENT_ANNOUNCE_TEXTURES); - writeU16(os, texture_announcements.size()); - - for(core::list::Iterator - j = texture_announcements.begin(); - j != texture_announcements.end(); j++){ + for(core::list::Iterator + j = file_announcements.begin(); + j != file_announcements.end(); j++){ os<name); os<sha1_digest); } @@ -4058,13 +4057,13 @@ void Server::SendTextureAnnouncement(u16 peer_id){ } -struct SendableTexture +struct SendableMedia { std::string name; std::string path; std::string data; - SendableTexture(const std::string &name_="", const std::string path_="", + SendableMedia(const std::string &name_="", const std::string path_="", const std::string &data_=""): name(name_), path(path_), @@ -4072,36 +4071,40 @@ struct SendableTexture {} }; -void Server::SendTexturesRequested(u16 peer_id,core::list tosend) { +void Server::sendRequestedMedia(u16 peer_id, + const core::list &tosend) +{ DSTACK(__FUNCTION_NAME); - verbosestream<<"Server::SendTexturesRequested(): " - <<"Sending textures to client"< > texture_bunches; - texture_bunches.push_back(core::list()); + core::array< core::list > file_bunches; + file_bunches.push_back(core::list()); - u32 texture_size_bunch_total = 0; + u32 file_size_bunch_total = 0; - for(core::list::Iterator i = tosend.begin(); i != tosend.end(); i++) { - if(m_Textures.find(i->name) == m_Textures.end()){ - errorstream<<"Server::SendTexturesRequested(): Client asked for " - <<"unknown texture \""<<(i->name)<<"\""<::ConstIterator i = tosend.begin(); + i != tosend.end(); i++) + { + if(m_media.find(i->name) == m_media.end()){ + errorstream<<"Server::sendRequestedMedia(): Client asked for " + <<"unknown file \""<<(i->name)<<"\""< tosend fis.read(buf, 1024); std::streamsize len = fis.gcount(); tmp_os.write(buf, len); - texture_size_bunch_total += len; + file_size_bunch_total += len; if(fis.eof()) break; if(!fis.good()){ @@ -4121,67 +4124,66 @@ void Server::SendTexturesRequested(u16 peer_id,core::list tosend } } if(bad){ - errorstream<<"Server::SendTexturesRequested(): Failed to read \"" + errorstream<<"Server::sendRequestedMedia(): Failed to read \"" <<(*i).name<<"\""<= bytes_per_bunch){ - texture_bunches.push_back(core::list()); - texture_size_bunch_total = 0; + if(file_size_bunch_total >= bytes_per_bunch){ + file_bunches.push_back(core::list()); + file_size_bunch_total = 0; } } /* Create and send packets */ - u32 num_bunches = texture_bunches.size(); - for(u32 i=0; i::Iterator - j = texture_bunches[i].begin(); - j != texture_bunches[i].end(); j++){ - os<name); - os<data); + /* + u16 command + u16 total number of texture bunches + u16 index of this bunch + u32 number of files in this bunch + for each file { + u16 length of name + string name + u32 length of data + data } + */ - // Make data buffer - std::string s = os.str(); - verbosestream<<"Server::SendTexturesRequested(): bunch " - < tosend); + void fillMediaCache(); + void sendMediaAnnouncement(u16 peer_id); + void sendRequestedMedia(u16 peer_id, + const core::list &tosend); /* Something random @@ -832,7 +831,7 @@ private: friend class EmergeThread; friend class RemoteClient; - std::map m_Textures; + std::map m_media; /* Sounds