From 788d81ba7e8dc97edfeccd55897d657c5cf8a21f Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Thu, 7 Apr 2011 23:51:22 +0000 Subject: [PATCH] - added code to download and display image preview for mod selections if they exist --- source/glest_game/main/main.cpp | 6 + source/glest_game/menu/menu_state_mods.cpp | 120 ++++++++++++++++-- source/glest_game/menu/menu_state_mods.h | 17 ++- .../include/platform/posix/miniftpclient.h | 14 +- .../sources/platform/posix/miniftpclient.cpp | 110 ++++++++++++++-- 5 files changed, 246 insertions(+), 21 deletions(-) diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 80b0f1d3..589bcc3d 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -2047,6 +2047,12 @@ int glestMain(int argc, char** argv) { } setCRCCacheFilePath(crcCachePath); + string tempDataPath = userData + "temp/"; + if(isdir(tempDataPath.c_str()) == true) { + removeFolder(tempDataPath); + } + createDirectoryPaths(tempDataPath); + if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_SOUND]) == true) { config.setString("FactorySound","None"); } diff --git a/source/glest_game/menu/menu_state_mods.cpp b/source/glest_game/menu/menu_state_mods.cpp index a82aa4c2..7595ee70 100644 --- a/source/glest_game/menu/menu_state_mods.cpp +++ b/source/glest_game/menu/menu_state_mods.cpp @@ -42,13 +42,14 @@ struct FormatString { // class ModInfo // =============================== -ModInfo::ModInfo(){ - name= ""; - url= ""; - imageUrl= ""; - description= ""; - count= ""; - crc= ""; +ModInfo::ModInfo() { + name = ""; + url = ""; + imageUrl = ""; + description = ""; + count = ""; + crc = ""; + type = mt_None; } @@ -64,6 +65,9 @@ MenuStateMods::MenuStateMods(Program *program, MainMenu *mainMenu) : Lang &lang= Lang::getInstance(); Config &config = Config::getInstance(); + modPreviewImage = NULL; + displayModPreviewImage = false; + ftpClientThread = NULL; selectedTechName = ""; selectedTilesetName = ""; @@ -381,6 +385,7 @@ void MenuStateMods::simpleTask(BaseThread *callingThread) { modinfo.description = tilesetInfoList[2]; modinfo.url = tilesetInfoList[3]; modinfo.imageUrl = tilesetInfoList[4]; + modinfo.type = mt_Tileset; //bool alreadyHasTileset = (std::find(tilesetFiles.begin(),tilesetFiles.end(),tilesetName) != tilesetFiles.end()); tilesetCacheList[modinfo.name] = modinfo; @@ -437,6 +442,7 @@ void MenuStateMods::simpleTask(BaseThread *callingThread) { modinfo.description = techInfoList[3]; modinfo.url = techInfoList[4]; modinfo.imageUrl = techInfoList[5]; + modinfo.type = mt_Techtree; //bool alreadyHasTech = (std::find(techTreeFiles.begin(),techTreeFiles.end(),techName) != techTreeFiles.end()); techCacheList[modinfo.name] = modinfo; @@ -509,6 +515,7 @@ void MenuStateMods::simpleTask(BaseThread *callingThread) { modinfo.description = mapInfoList[3]; modinfo.url = mapInfoList[4]; modinfo.imageUrl = mapInfoList[5]; + modinfo.type = mt_Map; //bool alreadyHasMap = (std::find(mapFiles.begin(),mapFiles.end(),mapName) != mapFiles.end()); mapCacheList[modinfo.name] = modinfo; @@ -577,7 +584,7 @@ void MenuStateMods::simpleTask(BaseThread *callingThread) { modinfo.description = scenarioInfoList[2]; modinfo.url = scenarioInfoList[3]; modinfo.imageUrl = scenarioInfoList[4]; - + modinfo.type = mt_Scenario; scenarioCacheList[modinfo.name] = modinfo; @@ -706,6 +713,7 @@ void MenuStateMods::refreshTechs() { modinfo.description = techInfoList[3]; modinfo.url = techInfoList[4]; modinfo.imageUrl = techInfoList[5]; + modinfo.type = mt_Techtree; techCacheList[modinfo.name] = modinfo; } } @@ -738,6 +746,7 @@ void MenuStateMods::refreshTilesets() { modinfo.description = tilesetInfoList[2]; modinfo.url = tilesetInfoList[3]; modinfo.imageUrl = tilesetInfoList[4]; + modinfo.type = mt_Tileset; tilesetCacheList[modinfo.name] = modinfo; } @@ -793,6 +802,7 @@ void MenuStateMods::refreshMaps() { modinfo.description = mapInfoList[3]; modinfo.url = mapInfoList[4]; modinfo.imageUrl = mapInfoList[5]; + modinfo.type = mt_Map; mapCacheList[modinfo.name] = modinfo; } } @@ -826,6 +836,7 @@ void MenuStateMods::refreshScenarios() { modinfo.description = scenarioInfoList[2]; modinfo.url = scenarioInfoList[3]; modinfo.imageUrl = scenarioInfoList[4]; + modinfo.type = mt_Scenario; } } } @@ -862,6 +873,8 @@ void MenuStateMods::cleanUp() { } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); } + + cleanupPreviewTexture(); } MenuStateMods::~MenuStateMods() { @@ -1413,8 +1426,53 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); } +string MenuStateMods::getPreviewImageFileForMod(const ModInfo *modInfo) { + string fileName = ""; + if(modInfo->imageUrl != "") { + Config &config = Config::getInstance(); + string userData = config.getString("UserData_Root",""); + if(userData != "") { + endPathWithSlash(userData); + } + string tempPath = userData + "temp/"; + if(isdir(tempPath.c_str()) == true) { + fileName = tempPath; + switch(modInfo->type) { + case mt_Map: + fileName += "map_"; + break; + case mt_Tileset: + fileName += "tileset_"; + break; + case mt_Techtree: + fileName += "tech_"; + break; + case mt_Scenario: + fileName += "scenario_"; + break; + } + fileName += extractFileFromDirectoryPath(modInfo->imageUrl); + } + } + return fileName; +} + void MenuStateMods::showDesription(const ModInfo *modInfo) { + displayModPreviewImage = false; + modInfoSelected = *modInfo; modDescrLabel.setText(modInfo->description); + + //printf("### modInfo->imageUrl [%s]\n",modInfo->imageUrl.c_str()); + + if(modInfo->imageUrl != "") { + string tempImage = getPreviewImageFileForMod(modInfo); + if(tempImage != "" && fileExists(tempImage) == false) { + ftpClientThread->addFileToRequests(tempImage,modInfo->imageUrl); + } + else { + displayModPreviewImage = true; + } + } } void MenuStateMods::mouseMove(int x, int y, const MouseState *ms) { @@ -1468,6 +1526,16 @@ void MenuStateMods::mouseMove(int x, int y, const MouseState *ms) { } } +void MenuStateMods::cleanupPreviewTexture() { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] scenarioLogoTexture [%p]\n",__FILE__,__FUNCTION__,__LINE__,modPreviewImage); + + if(modPreviewImage != NULL) { + Renderer::getInstance().endTexture(rsGlobal, modPreviewImage, false); + } + modPreviewImage = NULL; +} + + void MenuStateMods::render() { try { Renderer &renderer= Renderer::getInstance(); @@ -1487,6 +1555,21 @@ void MenuStateMods::render() { renderer.renderButton(&buttonRemoveScenario); renderer.renderLabel(&modDescrLabel); + if(displayModPreviewImage == true) { + if(modPreviewImage == NULL) { + string tempImage = getPreviewImageFileForMod(&modInfoSelected); + + //printf("### Render tempImage [%s] fileExists(tempImage) = %d\n",tempImage.c_str(),fileExists(tempImage)); + + if(tempImage != "" && fileExists(tempImage) == true) { + cleanupPreviewTexture(); + modPreviewImage = Renderer::findFactionLogoTexture(tempImage); + } + } + if(modPreviewImage != NULL) { + renderer.renderTextureQuad(508,90,485,325,modPreviewImage,1.0f); + } + } // Render Tech List renderer.renderLabel(&keyTechScrollBarTitle1); @@ -1753,6 +1836,27 @@ void MenuStateMods::FTPClient_CallbackEvent(string itemName, safeMutexFTPProgress.ReleaseLock(); } } + else if(type == ftp_cct_File) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] result = %d [%s]\n",itemName.c_str(),result.first,result.second.c_str()); + + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(); + + //printf("### downloaded file [%s] result = %d\n",itemName.c_str(),result.first); + + if(result.first == ftp_crt_SUCCESS) { + displayModPreviewImage = true; + } +// else { +// curl_version_info_data *curlVersion= curl_version_info(CURLVERSION_NOW); +// +// char szBuf[1024]=""; +// sprintf(szBuf,lang.get("ModDownloadMapFail").c_str(),itemName.c_str(),curlVersion->version,result.second.c_str()); +// console.addLine(szBuf,true); +// } + } + else if(type == ftp_cct_Map) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] result = %d [%s]\n",itemName.c_str(),result.first,result.second.c_str()); diff --git a/source/glest_game/menu/menu_state_mods.h b/source/glest_game/menu/menu_state_mods.h index f4932d41..e0f3e309 100644 --- a/source/glest_game/menu/menu_state_mods.h +++ b/source/glest_game/menu/menu_state_mods.h @@ -31,6 +31,14 @@ enum FTPMessageType { ftpmsg_Quit }; +enum ModType { + mt_None, + mt_Map, + mt_Tileset, + mt_Techtree, + mt_Scenario +}; + typedef vector UserButtons; typedef vector GraphicLabels; @@ -38,7 +46,7 @@ typedef vector GraphicLabels; // class ModInfo // =============================== -class ModInfo{ +class ModInfo { public: string name; string url; @@ -46,6 +54,7 @@ public: string description; string count; // used for faction count for example string crc; + ModType type; public: ModInfo(); }; @@ -102,6 +111,9 @@ private: UserButtons keyScenarioButtons; GraphicLabel modDescrLabel; + Texture2D *modPreviewImage; + ModInfo modInfoSelected; + bool displayModPreviewImage; int keyButtonsToRender; int keyButtonsYBase; @@ -180,6 +192,9 @@ private: void clearUserButtons(); virtual void FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, pair result,void *userdata); + + string getPreviewImageFileForMod(const ModInfo *modInfo); + void cleanupPreviewTexture(); }; }}//end namespace diff --git a/source/shared_lib/include/platform/posix/miniftpclient.h b/source/shared_lib/include/platform/posix/miniftpclient.h index d3b93ff4..b717dcd0 100644 --- a/source/shared_lib/include/platform/posix/miniftpclient.h +++ b/source/shared_lib/include/platform/posix/miniftpclient.h @@ -38,7 +38,8 @@ enum FTP_Client_CallbackType { ftp_cct_Tileset = 1, ftp_cct_Techtree = 2, ftp_cct_Scenario = 3, - ftp_cct_DownloadProgress = 4 + ftp_cct_File = 4, + ftp_cct_DownloadProgress = 5 }; class FTPClientCallbackInterface { @@ -50,6 +51,7 @@ public: double upload_total; double upload_now; string currentFilename; + FTP_Client_CallbackType downloadType; }; virtual void FTPClient_CallbackEvent(string itemName, @@ -79,6 +81,9 @@ protected: Mutex mutexScenarioList; vector > scenarioList; + Mutex mutexFileList; + vector > fileList; + void getMapFromServer(pair mapFilename); pair getMapFromServer(pair mapFileName, string ftpUser, string ftpUserPassword); @@ -91,13 +96,17 @@ protected: void getScenarioFromServer(pair fileName); pair getScenarioInternalFromServer(pair fileName); + void getFileFromServer(pair fileName); + pair getFileInternalFromServer(pair fileName); + Mutex mutexProgressMutex; string fileArchiveExtension; string fileArchiveExtractCommand; string fileArchiveExtractCommandParameters; - pair getFileFromServer(pair fileNameTitle, + pair getFileFromServer(FTP_Client_CallbackType downloadType, + pair fileNameTitle, string remotePath, string destFileSaveAs, string ftpUser, string ftpUserPassword, vector *wantDirListOnly=NULL); @@ -120,6 +129,7 @@ public: void addTilesetToRequests(string tileSetName,string URL=""); void addTechtreeToRequests(string techtreeName,string URL=""); void addScenarioToRequests(string fileName,string URL=""); + void addFileToRequests(string fileName,string URL=""); FTPClientCallbackInterface * getCallBackObject(); void setCallBackObject(FTPClientCallbackInterface *value); diff --git a/source/shared_lib/sources/platform/posix/miniftpclient.cpp b/source/shared_lib/sources/platform/posix/miniftpclient.cpp index 1f902efa..accc7d56 100644 --- a/source/shared_lib/sources/platform/posix/miniftpclient.cpp +++ b/source/shared_lib/sources/platform/posix/miniftpclient.cpp @@ -49,6 +49,7 @@ struct FtpFile { FTPClientThread *ftpServer; string currentFilename; bool isValidXfer; + FTP_Client_CallbackType downloadType; }; static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) { @@ -201,6 +202,7 @@ int file_progress(struct FtpFile *out,double download_total, double download_now stats.upload_total = upload_total; stats.upload_now = upload_now; stats.currentFilename = out->currentFilename; + stats.downloadType = out->downloadType; MutexSafeWrapper safeMutex(out->ftpServer->getProgressMutex(),string(__FILE__) + "_" + intToStr(__LINE__)); out->ftpServer->getCallBackObject()->FTPClient_CallbackEvent(out->itemName, ftp_cct_DownloadProgress, make_pair(ftp_crt_SUCCESS,""), &stats); @@ -274,7 +276,8 @@ pair FTPClientThread::getMapFromServer(pair item = make_pair(fileName,URL); + MutexSafeWrapper safeMutex(&mutexFileList,string(__FILE__) + "_" + intToStr(__LINE__)); + if(std::find(fileList.begin(),fileList.end(),item) == fileList.end()) { + fileList.push_back(item); + } +} + void FTPClientThread::getTilesetFromServer(pair tileSetName) { bool findArchive = executeShellCommand(this->fileArchiveExtractCommand); @@ -652,8 +663,8 @@ pair FTPClientThread::getTilesetFromServer(pair result = getFileFromServer(tileSetName, - remotePath, destFileSaveAs,ftpUser, ftpUserPassword, pWantDirListOnly); + pair result = getFileFromServer(ftp_cct_Tileset, + tileSetName, remotePath, destFileSaveAs,ftpUser, ftpUserPassword, pWantDirListOnly); // Extract the archive if(result.first == ftp_crt_SUCCESS) { @@ -683,7 +694,8 @@ pair FTPClientThread::getTilesetFromServer(pair FTPClientThread::getTechtreeFromServer(pair< remotePath = techtreeName.second; } - pair result = getFileFromServer(techtreeName, - remotePath, destFileSaveAs, ftpUser, ftpUserPassword); + pair result = getFileFromServer(ftp_cct_Techtree, + techtreeName, remotePath, destFileSaveAs, ftpUser, ftpUserPassword); // Extract the archive if(result.first == ftp_crt_SUCCESS) { @@ -935,8 +947,8 @@ pair FTPClientThread::getScenarioInternalFromServ remotePath = fileName.second; } - pair result = getFileFromServer(fileName, - remotePath, destFileSaveAs, "", ""); + pair result = getFileFromServer(ftp_cct_Scenario, + fileName, remotePath, destFileSaveAs, "", ""); // Extract the archive if(result.first == ftp_crt_SUCCESS) { @@ -954,7 +966,72 @@ pair FTPClientThread::getScenarioInternalFromServ } -pair FTPClientThread::getFileFromServer(pair fileNameTitle, +void FTPClientThread::getFileFromServer(pair fileName) { + pair result = make_pair(ftp_crt_FAIL,""); + + bool findArchive = true; + string ext = extractExtension(fileName.first); + if(ext == "7z") { + findArchive = executeShellCommand(this->fileArchiveExtractCommand); + } + if(findArchive == true) { + result = getFileInternalFromServer(fileName); + } + + MutexSafeWrapper safeMutex(this->getProgressMutex(),string(__FILE__) + "_" + intToStr(__LINE__)); + if(this->pCBObject != NULL) { + this->pCBObject->FTPClient_CallbackEvent(fileName.first,ftp_cct_File,result,NULL); + } +} + +pair FTPClientThread::getFileInternalFromServer(pair fileName) { + // Root folder for the techtree + //string destRootFolder = this->scenariosPath.second; + //endPathWithSlash(destRootFolder); + //string destRootArchiveFolder = destRootFolder; + //destRootFolder += fileName.first; + //endPathWithSlash(destRootFolder); + + //string destFile = this->scenariosPath.second; + //endPathWithSlash(destFile); + //destFile += fileName.first; + //string destFileSaveAs = destFile + this->fileArchiveExtension; + //endPathWithSlash(destFile); + + string destFile = fileName.first; + string destFileSaveAs = fileName.first; + + //string remotePath = fileName.first + this->fileArchiveExtension; + //if(fileName.second != "") { + // remotePath = fileName.second; + //} + + string remotePath = fileName.second; + + pair result = getFileFromServer(ftp_cct_File, + fileName,remotePath, destFileSaveAs, "", ""); + + // Extract the archive + if(result.first == ftp_crt_SUCCESS) { + string ext = extractExtension(destFileSaveAs); + if(ext == "7z") { + string destRootArchiveFolder = extractDirectoryPathFromFile(destFileSaveAs); + string extractCmd = getFullFileArchiveExtractCommand(this->fileArchiveExtractCommand, + this->fileArchiveExtractCommandParameters, destRootArchiveFolder, + destFileSaveAs); + + if(executeShellCommand(extractCmd) == false) { + result.first = ftp_crt_FAIL; + result.second = "failed to extract archive!"; + } + } + } + + return result; +} + +pair FTPClientThread::getFileFromServer(FTP_Client_CallbackType downloadType, + pair fileNameTitle, string remotePath, string destFileSaveAs, string ftpUser, string ftpUserPassword, vector *wantDirListOnly) { pair result = make_pair(ftp_crt_FAIL,""); @@ -980,7 +1057,8 @@ pair FTPClientThread::getFileFromServer(pair 0) { + pair file = fileList[0]; + fileList.erase(fileList.begin() + 0); + safeMutex5.ReleaseLock(); + + getFileFromServer(file); + } + else { + safeMutex5.ReleaseLock(); + } + if(this->getQuitStatus() == false) { sleep(25); }