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/server.cpp | 324 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 232 insertions(+), 92 deletions(-) (limited to 'src/server.cpp') diff --git a/src/server.cpp b/src/server.cpp index 3679195f3..5bd072d02 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -48,6 +48,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen.h" #include "content_abm.h" #include "mods.h" +#include "sha1.h" +#include "base64.h" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" @@ -929,6 +931,9 @@ Server::Server( } } + // Read Textures and calculate sha1 sums + PrepareTextures(); + // Initialize Environment m_env = new ServerEnvironment(new ServerMap(mapsavedir, this), m_lua, @@ -2110,8 +2115,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) // Send CraftItem definitions SendCraftItemDef(m_con, peer_id, m_craftitemdef); - // Send textures - SendTextures(peer_id); + // Send texture announcement + SendTextureAnnouncement(peer_id); // Send player info to all players //SendPlayerInfos(); @@ -2825,6 +2830,26 @@ 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) { + std::string datastring((char*)&data[2], datasize-2); + std::istringstream is(datastring, std::ios_base::binary); + + infostream<<"TOSERVER_REQUEST_TEXTURES: "< tosend; + + u16 numtextures = readU16(is); + + for(int i = 0; i < numtextures; i++) { + + std::string name = deSerializeString(is); + + tosend.push_back(TextureRequest(name)); + infostream<<"TOSERVER_REQUEST_TEXTURES: requested texture " << name <::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); + for(u32 j=0; jm_Textures[tname] = TextureInformation(tpath,digest_string); + infostream<<"Server::PrepareTextures(): added sha1 for "<< tname < texture_announcements; + + for (std::map::iterator i = m_Textures.begin();i != m_Textures.end(); i++ ) { + + // Put in list + texture_announcements.push_back( + SendableTextureAnnouncement(i->first, i->second.sha1_digest)); + } + + //send announcements + + /* + u16 command + u32 number of textures + for each texture { + u16 length of name + string name + u16 length of digest string + string sha1_digest + } + */ + std::ostringstream os(std::ios_base::binary); + + writeU16(os, TOCLIENT_ANNOUNCE_TEXTURES); + writeU16(os, texture_announcements.size()); + + for(core::list::Iterator + j = texture_announcements.begin(); + j != texture_announcements.end(); j++){ + os<name); + os<sha1_digest); + } + + // Make data buffer + std::string s = os.str(); + infostream<<"Server::SendTextureAnnouncement(): Send to client"< data((u8*)s.c_str(), s.size()); + + // Send as reliable + m_con.Send(peer_id, 0, data, true); + +} + struct SendableTexture { std::string name; @@ -4247,112 +4390,109 @@ struct SendableTexture {} }; -void Server::SendTextures(u16 peer_id) -{ +void Server::SendTexturesRequested(u16 peer_id,core::list tosend) { DSTACK(__FUNCTION_NAME); - infostream<<"Server::SendTextures(): Sending textures to client"< > texture_bunches; texture_bunches.push_back(core::list()); - + u32 texture_size_bunch_total = 0; - for(core::list::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); - for(u32 j=0; j= bytes_per_bunch){ - texture_bunches.push_back(core::list()); - texture_size_bunch_total = 0; + + for(core::list::Iterator i = tosend.begin(); i != tosend.end(); i++) { + + //TODO get path + name + std::string tpath = m_Textures[(*i).name].path; + + // Read data + std::ifstream fis(tpath.c_str(), std::ios_base::binary); + if(fis.good() == false){ + errorstream<<"Server::SendTexturesRequested(): Could not open \"" + <= bytes_per_bunch){ + texture_bunches.push_back(core::list()); + texture_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); } - */ - std::ostringstream os(std::ios_base::binary); - writeU16(os, TOCLIENT_TEXTURES); - writeU16(os, num_bunches); - writeU16(os, i); - writeU32(os, texture_bunches[i].size()); - - for(core::list::Iterator - j = texture_bunches[i].begin(); - j != texture_bunches[i].end(); j++){ - os<name); - os<data); + // Make data buffer + std::string s = os.str(); + infostream<<"Server::SendTexturesRequested(): bunch "<