From 817d8cfea86fa6f30edc85a90d49e996faf01deb Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Wed, 9 Mar 2011 18:35:19 +0000 Subject: [PATCH] - added logic for ftp file transfers to look for 7z archives for tilesets and download and extract on the client side if the 7z archive exists on the server --- mk/linux/glest.ini | 3 + .../menu/menu_state_connected_game.cpp | 8 +- .../include/platform/common/platform_common.h | 3 + .../include/platform/posix/miniftpclient.h | 14 ++- .../platform/common/platform_common.cpp | 34 +++++++ .../sources/platform/posix/miniftpclient.cpp | 89 +++++++++++++------ 6 files changed, 123 insertions(+), 28 deletions(-) diff --git a/mk/linux/glest.ini b/mk/linux/glest.ini index 292a2fd7..1185cb08 100644 --- a/mk/linux/glest.ini +++ b/mk/linux/glest.ini @@ -29,6 +29,9 @@ DepthBits=16 FactoryGraphics=OpenGL FactorySound=OpenAL FastSpeedLoops=2 +FileArchiveExtension=.7z +FileArchiveExtractCommand=7z +FileArchiveExtractCommandParameters=x -o{outputpath} {archivename} Filter=Bilinear FilterMaxAnisotropy=1 FirstTime=false diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 7ccd1ed9..930e80b1 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -412,7 +412,13 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM } } - ftpClientThread = new FTPClientThread(portNumber,serverUrl,mapsPath,tilesetsPath,this); + string fileArchiveExtension = config.getString("FileArchiveExtension",""); + string fileArchiveExtractCommand = config.getString("FileArchiveExtractCommand",""); + string fileArchiveExtractCommandParameters = config.getString("FileArchiveExtractCommandParameters",""); + + ftpClientThread = new FTPClientThread(portNumber,serverUrl,mapsPath, + tilesetsPath,this,fileArchiveExtension,fileArchiveExtractCommand, + fileArchiveExtractCommandParameters); ftpClientThread->start(); } diff --git a/source/shared_lib/include/platform/common/platform_common.h b/source/shared_lib/include/platform/common/platform_common.h index e63a77bf..708a93b7 100644 --- a/source/shared_lib/include/platform/common/platform_common.h +++ b/source/shared_lib/include/platform/common/platform_common.h @@ -166,6 +166,9 @@ inline string trim (const string & s, const string & t = SPACES) { return trim_left (trim_right (d, t), t) ; } // end of trim +string getFullFileArchiveExtractCommand(string fileArchiveExtractCommand, + string fileArchiveExtractCommandParameters, string outputpath, string archivename); +bool executeShellCommand(string cmd); class ValueCheckerVault { diff --git a/source/shared_lib/include/platform/posix/miniftpclient.h b/source/shared_lib/include/platform/posix/miniftpclient.h index 4fa39aab..33832144 100644 --- a/source/shared_lib/include/platform/posix/miniftpclient.h +++ b/source/shared_lib/include/platform/posix/miniftpclient.h @@ -72,13 +72,23 @@ protected: FTP_Client_ResultType getMapFromServer(string mapFileName, string ftpUser, string ftpUserPassword); void getTilesetFromServer(string tileSetName); - FTP_Client_ResultType getTilesetFromServer(string tileSetName, string tileSetNameSubfolder, string ftpUser, string ftpUserPassword); + FTP_Client_ResultType getTilesetFromServer(string tileSetName, string tileSetNameSubfolder, string ftpUser, string ftpUserPassword, bool findArchive); Mutex mutexProgressMutex; + string fileArchiveExtension; + string fileArchiveExtractCommand; + string fileArchiveExtractCommandParameters; + public: - FTPClientThread(int portNumber,string serverUrl, std::pair mapsPath, std::pair tilesetsPath, FTPClientCallbackInterface *pCBObject); + FTPClientThread(int portNumber,string serverUrl, + std::pair mapsPath, + std::pair tilesetsPath, + FTPClientCallbackInterface *pCBObject, + string fileArchiveExtension, + string fileArchiveExtractCommand, + string fileArchiveExtractCommandParameters); virtual void execute(); virtual void signalQuit(); virtual bool shutdownAndWait(); diff --git a/source/shared_lib/sources/platform/common/platform_common.cpp b/source/shared_lib/sources/platform/common/platform_common.cpp index 6e10ccbb..956f4efb 100644 --- a/source/shared_lib/sources/platform/common/platform_common.cpp +++ b/source/shared_lib/sources/platform/common/platform_common.cpp @@ -1086,6 +1086,40 @@ string replaceAll(string& context, const string& from, const string& to) { return context; } +string getFullFileArchiveExtractCommand(string fileArchiveExtractCommand, + string fileArchiveExtractCommandParameters, string outputpath, string archivename) { + string result = fileArchiveExtractCommand; + result += " "; + string args = replaceAll(fileArchiveExtractCommandParameters, "{outputpath}", outputpath); + args = replaceAll(args, "{archivename}", archivename); + result += args; + + return result; +} + +bool executeShellCommand(string cmd) { + bool result = false; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nAbout to run [%s]", cmd.c_str()); + + FILE *file = popen(cmd.c_str(),"r"); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nfile = [%p]", file); + + if(file != NULL) { + char szBuf[4096]=""; + while(feof(file) == false) { + if(fgets( szBuf, 4095, file) != NULL) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s",szBuf); + } + } + + int cmdRet = pclose(file); + /* Close pipe and print return value. */ + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nProcess returned %d", cmdRet); + result = true; + } + return result; +} + // ===================================== // ModeInfo // ===================================== diff --git a/source/shared_lib/sources/platform/posix/miniftpclient.cpp b/source/shared_lib/sources/platform/posix/miniftpclient.cpp index f1ffb836..d8877957 100644 --- a/source/shared_lib/sources/platform/posix/miniftpclient.cpp +++ b/source/shared_lib/sources/platform/posix/miniftpclient.cpp @@ -193,13 +193,20 @@ int file_progress(struct FtpFile *out,double download_total, double download_now return 0; } -FTPClientThread::FTPClientThread(int portNumber, string serverUrl, std::pair mapsPath, std::pair tilesetsPath, FTPClientCallbackInterface *pCBObject) : BaseThread() { +FTPClientThread::FTPClientThread(int portNumber, string serverUrl, + std::pair mapsPath, std::pair tilesetsPath, + FTPClientCallbackInterface *pCBObject,string fileArchiveExtension, + string fileArchiveExtractCommand,string fileArchiveExtractCommandParameters) : BaseThread() { this->portNumber = portNumber; this->serverUrl = serverUrl; this->mapsPath = mapsPath; this->tilesetsPath = tilesetsPath; this->pCBObject = pCBObject; + this->fileArchiveExtension = fileArchiveExtension; + this->fileArchiveExtractCommand = fileArchiveExtractCommand; + this->fileArchiveExtractCommandParameters = fileArchiveExtractCommandParameters; + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] Using FTP port #: %d, serverUrl [%s]\n",__FILE__,__FUNCTION__,__LINE__,portNumber,serverUrl.c_str()); } @@ -331,9 +338,11 @@ void FTPClientThread::addTilesetToRequests(string tileSetName) { } void FTPClientThread::getTilesetFromServer(string tileSetName) { - FTP_Client_ResultType result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); + bool findArchive = executeShellCommand(this->fileArchiveExtractCommand); + + FTP_Client_ResultType result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, findArchive); if(result == ftp_crt_FAIL && this->getQuitStatus() == false) { - result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD); + result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, findArchive); } MutexSafeWrapper safeMutex(this->getProgressMutex(),string(__FILE__) + "_" + intToStr(__LINE__)); @@ -342,20 +351,26 @@ void FTPClientThread::getTilesetFromServer(string tileSetName) { } } -FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, string tileSetNameSubfolder, string ftpUser, string ftpUserPassword) { +FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, + string tileSetNameSubfolder, string ftpUser, string ftpUserPassword, + bool findArchive) { FTP_Client_ResultType result = ftp_crt_FAIL; string destFile = this->tilesetsPath.second; // Root folder for the tileset + string destRootArchiveFolder = ""; string destRootFolder = ""; if(tileSetNameSubfolder == "") { destRootFolder = this->tilesetsPath.second; - if(EndsWith(destRootFolder,"/") == false && EndsWith(destRootFolder,"\\") == false) { + if( EndsWith(destRootFolder,"/") == false && + EndsWith(destRootFolder,"\\") == false) { destRootFolder += "/"; } + destRootArchiveFolder = destRootFolder; destRootFolder += tileSetName; - if(EndsWith(destRootFolder,"/") == false && EndsWith(destRootFolder,"\\") == false) { + if( EndsWith(destRootFolder,"/") == false && + EndsWith(destRootFolder,"\\") == false) { destRootFolder += "/"; } @@ -378,8 +393,8 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, } } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread about to try to RETR into [%s]\n",destFile.c_str()); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread about to try to RETR into [%s]\n",destFile.c_str()); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread about to try to RETR into [%s] findArchive = %d\n",destFile.c_str(),findArchive); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread about to try to RETR into [%s] findArchive = %d\n",destFile.c_str(),findArchive); struct FtpFile ftpfile = { tileSetName.c_str(), @@ -391,6 +406,10 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, false }; + if(findArchive == true) { + ftpfile.filepath = destRootArchiveFolder.c_str(); + } + //curl_global_init(CURL_GLOBAL_DEFAULT); CURL *curl = SystemFlags::initHTTP(); @@ -399,7 +418,12 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, char szBuf[1024]=""; if(tileSetNameSubfolder == "") { - sprintf(szBuf,"ftp://%s:%s@%s:%d/%s/*",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,tileSetName.c_str()); + if(findArchive == true) { + sprintf(szBuf,"ftp://%s:%s@%s:%d/%s%s",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,tileSetName.c_str(),this->fileArchiveExtension.c_str()); + } + else { + sprintf(szBuf,"ftp://%s:%s@%s:%d/%s/*",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,tileSetName.c_str()); + } } else { sprintf(szBuf,"ftp://%s:%s@%s:%d/%s/%s/*",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,tileSetName.c_str(),tileSetNameSubfolder.c_str()); @@ -454,25 +478,28 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, result = ftp_crt_SUCCESS; bool requireMoreFolders = false; - if(tileSetNameSubfolder == "") { - tileSetNameSubfolder = "models"; - requireMoreFolders = true; - } - else if(tileSetNameSubfolder == "models") { - tileSetNameSubfolder = "sounds"; - requireMoreFolders = true; - } - else if(tileSetNameSubfolder == "sounds") { - tileSetNameSubfolder = "textures"; - requireMoreFolders = true; - } - else if(tileSetNameSubfolder == "textures") { - tileSetNameSubfolder = ""; - requireMoreFolders = false; + + if(findArchive == false) { + if(tileSetNameSubfolder == "") { + tileSetNameSubfolder = "models"; + requireMoreFolders = true; + } + else if(tileSetNameSubfolder == "models") { + tileSetNameSubfolder = "sounds"; + requireMoreFolders = true; + } + else if(tileSetNameSubfolder == "sounds") { + tileSetNameSubfolder = "textures"; + requireMoreFolders = true; + } + else if(tileSetNameSubfolder == "textures") { + tileSetNameSubfolder = ""; + requireMoreFolders = false; + } } if(requireMoreFolders == true) { - result = getTilesetFromServer(tileSetName, tileSetNameSubfolder, ftpUser, ftpUserPassword); + result = getTilesetFromServer(tileSetName, tileSetNameSubfolder, ftpUser, ftpUserPassword, false); if(result != ftp_crt_SUCCESS) { if(destRootFolder != "") { //unlink(destRootFolder.c_str()); @@ -489,6 +516,18 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, fclose(ftpfile.stream); ftpfile.stream = NULL; } + + // Extract the archive + if(findArchive == true && result == ftp_crt_SUCCESS) { + string extractCmd = getFullFileArchiveExtractCommand(this->fileArchiveExtractCommand, + this->fileArchiveExtractCommandParameters, destRootArchiveFolder, + destRootArchiveFolder + tileSetName + this->fileArchiveExtension); + + if(executeShellCommand(extractCmd) == false) { + result = ftp_crt_FAIL; + } + } + return result; }