Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- celeron55-minetest-6957930.orig/src/clientserver.h 2011-12-11 15:52:19.000000000 +0100
- +++ celeron55-minetest-6957930/src/clientserver.h 2012-01-02 00:45:57.000000000 +0100
- @@ -235,6 +235,19 @@
- u32 length of the next item
- serialized CraftiItemDefManager
- */
- +
- + TOCLIENT_ANNOUNCE_TEXTURES = 0x3c,
- +
- + /*
- + u16 command
- + u32 number of textures
- + for each texture {
- + u16 length of name
- + string name
- + u16 length of sha1_digest
- + string sha1_digest
- + }
- + */
- };
- enum ToServerCommand
- @@ -408,6 +421,17 @@
- (Obsoletes TOSERVER_GROUND_ACTION and TOSERVER_CLICK_ACTIVEOBJECT.)
- */
- + TOSERVER_REQUEST_TEXTURES = 0x40,
- +
- + /*
- + u16 command
- + u16 number of textures requested
- + for each texture {
- + u16 length of name
- + string name
- + }
- + */
- +
- };
- inline SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time)
- --- celeron55-minetest-6957930.orig/src/server.h 2011-12-11 15:52:19.000000000 +0100
- +++ celeron55-minetest-6957930/src/server.h 2012-01-02 01:11:16.000000000 +0100
- @@ -235,6 +235,28 @@
- u16 peer_id;
- };
- +struct TextureRequest
- +{
- + std::string name;
- +
- + TextureRequest(const std::string &name_=""):
- + name(name_)
- + {}
- +};
- +
- +struct TextureInformation
- +{
- + std::string path;
- + std::string sha1_digest;
- +
- + TextureInformation(const std::string path_="",
- + const std::string sha1_digest_=""):
- + path(path_),
- + sha1_digest(sha1_digest_)
- + {
- + }
- +};
- +
- class RemoteClient
- {
- public:
- @@ -563,7 +585,11 @@
- // Sends blocks to clients (locks env and con on its own)
- void SendBlocks(float dtime);
- - void SendTextures(u16 peer_id);
- + void PrepareTextures();
- +
- + void SendTextureAnnouncement(u16 peer_id);
- +
- + void SendTexturesRequested(u16 peer_id,core::list<TextureRequest> tosend);
- /*
- Something random
- @@ -743,6 +769,8 @@
- friend class EmergeThread;
- friend class RemoteClient;
- +
- + std::map<std::string,TextureInformation> m_Textures;
- };
- /*
- --- celeron55-minetest-6957930.orig/src/server.cpp 2011-12-11 15:52:19.000000000 +0100
- +++ celeron55-minetest-6957930/src/server.cpp 2012-01-02 01:42:54.000000000 +0100
- @@ -48,6 +48,8 @@
- #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<<")"
- @@ -924,6 +926,9 @@
- }
- }
- + // Read Textures and calculate sha1 sums
- + PrepareTextures();
- +
- // Initialize Environment
- m_env = new ServerEnvironment(new ServerMap(mapsavedir, this), m_lua,
- @@ -2105,8 +2110,8 @@
- // 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();
- @@ -2820,6 +2825,26 @@
- // 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: "<<std::endl;
- +
- + core::list<TextureRequest> 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 <<std::endl;
- + }
- +
- + SendTexturesRequested(peer_id, tosend);
- + }
- else if(command == TOSERVER_INTERACT)
- {
- std::string datastring((char*)&data[2], datasize-2);
- @@ -4174,6 +4199,124 @@
- }
- }
- +void Server::PrepareTextures() {
- + DSTACK(__FUNCTION_NAME);
- +
- + infostream<<"Server::PrepareTextures(): Calculate sha1 sums of textures"<<std::endl;
- +
- + for(core::list<ModSpec>::Iterator i = m_mods.begin();
- + i != m_mods.end(); i++){
- + const ModSpec &mod = *i;
- + std::string texturepath = mod.path + DIR_DELIM + "textures";
- + std::vector<fs::DirListNode> dirlist = fs::GetDirListing(texturepath);
- + for(u32 j=0; j<dirlist.size(); j++){
- + if(dirlist[j].dir) // Ignode dirs
- + continue;
- + std::string tname = dirlist[j].name;
- + std::string tpath = texturepath + DIR_DELIM + tname;
- + // Read data
- + std::ifstream fis(tpath.c_str(), std::ios_base::binary);
- + if(fis.good() == false){
- + errorstream<<"Server::PrepareTextures(): Could not open \""
- + <<tname<<"\" for reading"<<std::endl;
- + continue;
- + }
- + 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){
- + errorstream<<"Server::PrepareTextures(): Failed to read \""
- + <<tname<<"\""<<std::endl;
- + continue;
- + }
- +
- + 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);
- +
- + delete(digest);
- +
- + // Put in list
- + this->m_Textures[tname] = TextureInformation(tpath,digest_string);
- + infostream<<"Server::PrepareTextures(): added sha1 for "<< tname <<std::endl;
- + }
- + }
- +}
- +
- +struct SendableTextureAnnouncement
- + {
- + std::string name;
- + std::string sha1_digest;
- +
- + SendableTextureAnnouncement(const std::string name_="",
- + const std::string sha1_digest_=""):
- + name(name_),
- + sha1_digest(sha1_digest_)
- + {
- + }
- + };
- +
- +void Server::SendTextureAnnouncement(u16 peer_id){
- + DSTACK(__FUNCTION_NAME);
- +
- + infostream<<"Server::SendTextureAnnouncement(): Calculate sha1 sums of textures and send to client"<<std::endl;
- +
- + core::list<SendableTextureAnnouncement> texture_announcements;
- +
- + for (std::map<std::string,TextureInformation>::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<SendableTextureAnnouncement>::Iterator
- + j = texture_announcements.begin();
- + j != texture_announcements.end(); j++){
- + os<<serializeString(j->name);
- + os<<serializeString(j->sha1_digest);
- + }
- +
- + // Make data buffer
- + std::string s = os.str();
- + infostream<<"Server::SendTextureAnnouncement(): Send to client"<<std::endl;
- + SharedBuffer<u8> data((u8*)s.c_str(), s.size());
- +
- + // Send as reliable
- + m_con.Send(peer_id, 0, data, true);
- +
- +}
- +
- struct SendableTexture
- {
- std::string name;
- @@ -4188,112 +4331,109 @@
- {}
- };
- -void Server::SendTextures(u16 peer_id)
- -{
- +void Server::SendTexturesRequested(u16 peer_id,core::list<TextureRequest> tosend) {
- DSTACK(__FUNCTION_NAME);
- - infostream<<"Server::SendTextures(): Sending textures to client"<<std::endl;
- -
- + infostream<<"Server::SendTexturesRequested(): Sending textures to client"<<std::endl;
- +
- /* Read textures */
- -
- +
- // Put 5kB in one bunch (this is not accurate)
- u32 bytes_per_bunch = 5000;
- -
- +
- core::array< core::list<SendableTexture> > texture_bunches;
- texture_bunches.push_back(core::list<SendableTexture>());
- -
- +
- u32 texture_size_bunch_total = 0;
- - for(core::list<ModSpec>::Iterator i = m_mods.begin();
- - i != m_mods.end(); i++){
- - const ModSpec &mod = *i;
- - std::string texturepath = mod.path + DIR_DELIM + "textures";
- - std::vector<fs::DirListNode> dirlist = fs::GetDirListing(texturepath);
- - for(u32 j=0; j<dirlist.size(); j++){
- - if(dirlist[j].dir) // Ignode dirs
- - continue;
- - std::string tname = dirlist[j].name;
- - std::string tpath = texturepath + DIR_DELIM + tname;
- - // Read data
- - std::ifstream fis(tpath.c_str(), std::ios_base::binary);
- - if(fis.good() == false){
- - errorstream<<"Server::SendTextures(): Could not open \""
- - <<tname<<"\" for reading"<<std::endl;
- - continue;
- - }
- - 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);
- - texture_size_bunch_total += len;
- - if(fis.eof())
- - break;
- - if(!fis.good()){
- - bad = true;
- - break;
- - }
- - }
- - if(bad){
- - errorstream<<"Server::SendTextures(): Failed to read \""
- - <<tname<<"\""<<std::endl;
- - continue;
- - }
- - /*infostream<<"Server::SendTextures(): Loaded \""
- - <<tname<<"\""<<std::endl;*/
- - // Put in list
- - texture_bunches[texture_bunches.size()-1].push_back(
- - SendableTexture(tname, tpath, tmp_os.str()));
- -
- - // Start next bunch if got enough data
- - if(texture_size_bunch_total >= bytes_per_bunch){
- - texture_bunches.push_back(core::list<SendableTexture>());
- - texture_size_bunch_total = 0;
- +
- + for(core::list<TextureRequest>::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 \""
- + <<tpath<<"\" for reading"<<std::endl;
- + continue;
- + }
- + 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);
- + texture_size_bunch_total += len;
- + if(fis.eof())
- + break;
- + if(!fis.good()){
- + bad = true;
- + break;
- }
- }
- + if(bad){
- + errorstream<<"Server::SendTexturesRequested(): Failed to read \""
- + <<(*i).name<<"\""<<std::endl;
- + continue;
- + }
- + /*infostream<<"Server::SendTexturesRequested(): Loaded \""
- + <<tname<<"\""<<std::endl;*/
- + // Put in list
- + texture_bunches[texture_bunches.size()-1].push_back(
- + SendableTexture((*i).name, tpath, tmp_os.str()));
- +
- + // Start next bunch if got enough data
- + if(texture_size_bunch_total >= bytes_per_bunch){
- + texture_bunches.push_back(core::list<SendableTexture>());
- + texture_size_bunch_total = 0;
- + }
- +
- }
- /* Create and send packets */
- -
- - u32 num_bunches = texture_bunches.size();
- - for(u32 i=0; i<num_bunches; i++)
- - {
- - /*
- - u16 command
- - u16 total number of texture bunches
- - u16 index of this bunch
- - u32 number of textures in this bunch
- - for each texture {
- - u16 length of name
- - string name
- - u32 length of data
- - 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<SendableTexture>::Iterator
- - j = texture_bunches[i].begin();
- - j != texture_bunches[i].end(); j++){
- - os<<serializeString(j->name);
- - os<<serializeLongString(j->data);
- - }
- -
- - // Make data buffer
- - std::string s = os.str();
- - infostream<<"Server::SendTextures(): bunch "<<i<<"/"<<num_bunches
- - <<" textures="<<texture_bunches[i].size()
- - <<" size=" <<s.size()<<std::endl;
- - SharedBuffer<u8> data((u8*)s.c_str(), s.size());
- - // Send as reliable
- - m_con.Send(peer_id, 0, data, true);
- - }
- + u32 num_bunches = texture_bunches.size();
- + for(u32 i=0; i<num_bunches; i++)
- + {
- + /*
- + u16 command
- + u16 total number of texture bunches
- + u16 index of this bunch
- + u32 number of textures in this bunch
- + for each texture {
- + u16 length of name
- + string name
- + u32 length of data
- + 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<SendableTexture>::Iterator
- + j = texture_bunches[i].begin();
- + j != texture_bunches[i].end(); j++){
- + os<<serializeString(j->name);
- + os<<serializeLongString(j->data);
- + }
- +
- + // Make data buffer
- + std::string s = os.str();
- + infostream<<"Server::SendTexturesRequested(): bunch "<<i<<"/"<<num_bunches
- + <<" textures="<<texture_bunches[i].size()
- + <<" size=" <<s.size()<<std::endl;
- + SharedBuffer<u8> data((u8*)s.c_str(), s.size());
- + // Send as reliable
- + m_con.Send(peer_id, 0, data, true);
- + }
- +
- +
- }
- /*
- --- celeron55-minetest-6957930.orig/src/client.cpp 2011-12-11 15:52:19.000000000 +0100
- +++ celeron55-minetest-6957930/src/client.cpp 2012-01-02 01:38:37.000000000 +0100
- @@ -36,6 +36,17 @@
- #include "tooldef.h"
- #include "craftitemdef.h"
- #include <IFileSystem.h>
- +#include "sha1.h"
- +#include "base64.h"
- +
- +struct TextureRequest
- +{
- + std::string name;
- +
- + TextureRequest(const std::string &name_=""):
- + name(name_)
- + {}
- +};
- /*
- QueuedMeshUpdate
- @@ -1232,6 +1243,157 @@
- event.deathscreen.camera_point_target_z = camera_point_target.Z;
- m_client_event_queue.push_back(event);
- }
- + else if(command == TOCLIENT_ANNOUNCE_TEXTURES)
- + {
- + io::IFileSystem *irrfs = m_device->getFileSystem();
- + video::IVideoDriver *vdrv = m_device->getVideoDriver();
- +
- + std::string datastring((char*)&data[2], datasize-2);
- + std::istringstream is(datastring, std::ios_base::binary);
- +
- +
- + // Stop threads while updating content definitions
- + m_mesh_update_thread.setRun(false);
- + // Process the remaining TextureSource queue to let MeshUpdateThread
- + // get it's remaining textures and thus let it stop
- + while(m_mesh_update_thread.IsRunning()){
- + m_tsrc->processQueue();
- + }
- +
- + 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);
- +
- + std::string tpath = porting::path_userdata + DIR_DELIM + std::string("cache") + 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;
- + }
- +
- + delete(digest);
- + }
- + }
- +
- + //add texture request
- + if (!texture_found) {
- + infostream<<"Client: Adding texture to request list: \""
- + <<name<<"\""<<std::endl;
- + texture_requests.push_back(TextureRequest(name));
- + }
- +
- + }
- + // Resume threads
- + m_mesh_update_thread.setRun(true);
- + m_mesh_update_thread.Start();
- +
- + ClientEvent event;
- + event.type = CE_TEXTURES_UPDATED;
- + m_client_event_queue.push_back(event);
- +
- +
- + //send Texture request
- + /*
- + u16 command
- + u16 number of textures requested
- + for each texture {
- + u16 length of name
- + string name
- + u16 length of path
- + string path
- + }
- + */
- + std::ostringstream os(std::ios_base::binary);
- + u8 buf[12];
- +
- +
- + // Write command
- + writeU16(buf, TOSERVER_REQUEST_TEXTURES);
- + os.write((char*)buf, 2);
- +
- + writeU16(buf,texture_requests.size());
- + os.write((char*)buf, 2);
- +
- +
- + for(core::list<TextureRequest>::Iterator i = texture_requests.begin();
- + i != texture_requests.end(); i++) {
- + os<<serializeString(i->name);
- + }
- +
- + // Make data buffer
- + std::string s = os.str();
- + SharedBuffer<u8> data((u8*)s.c_str(), s.size());
- + // Send as reliable
- + Send(0, data, true);
- + infostream<<"Client: Sending request list to server " <<std::endl;
- + }
- else if(command == TOCLIENT_TEXTURES)
- {
- io::IFileSystem *irrfs = m_device->getFileSystem();
- @@ -1286,6 +1448,20 @@
- rfile->drop();
- continue;
- }
- +
- + fs::CreateDir(porting::path_userdata + DIR_DELIM + std::string("cache"));
- +
- + std::string filename = porting::path_userdata + DIR_DELIM + std::string("cache") + DIR_DELIM + name;
- + std::ofstream outfile(filename.c_str(), std::ios_base::binary | std::ios_base::trunc);
- +
- + if (outfile.good()) {
- + outfile.write(data.c_str(),data.length());
- + outfile.close();
- + }
- + else {
- + errorstream<<"Client: Unable to open cached texture file "<< filename <<std::endl;
- + }
- +
- m_tsrc->insertSourceImage(name, img);
- img->drop();
- rfile->drop();
- --- celeron55-minetest-6957930.orig/src/client.h 2011-12-11 15:52:19.000000000 +0100
- +++ celeron55-minetest-6957930/src/client.h 2012-01-01 03:41:44.000000000 +0100
- @@ -30,6 +30,7 @@
- #include "clientobject.h"
- #include "utility.h" // For IntervalLimiter
- #include "gamedef.h"
- +#include "filesys.h"
- struct MeshMakeData;
- class IGameDef;
Advertisement
Add Comment
Please, Sign In to add comment