diff --git a/source/glest_game/facilities/components.cpp b/source/glest_game/facilities/components.cpp index 9f148a53e..89e94e0fd 100644 --- a/source/glest_game/facilities/components.cpp +++ b/source/glest_game/facilities/components.cpp @@ -259,6 +259,12 @@ void GraphicLabel::init(int x, int y, int w, int h, bool centered){ const int GraphicButton::defH= 22; const int GraphicButton::defW= 90; +GraphicButton::GraphicButton(std::string containerName, std::string objName) : GraphicComponent(containerName,objName) { + lighted = false; + useCustomTexture = false;; + customTexture = NULL; +} + void GraphicButton::init(int x, int y, int w, int h){ GraphicComponent::init(x, y, w, h); lighted= false; diff --git a/source/glest_game/facilities/components.h b/source/glest_game/facilities/components.h index aac9bef2f..45949458f 100644 --- a/source/glest_game/facilities/components.h +++ b/source/glest_game/facilities/components.h @@ -17,12 +17,14 @@ #include #include #include "font.h" +#include "texture.h" #include "leak_dumper.h" using std::string; using std::vector; using Shared::Graphics::Font2D; +using namespace Shared::Graphics; namespace Glest{ namespace Game{ @@ -131,10 +133,20 @@ public: private: bool lighted; + + bool useCustomTexture; + Texture *customTexture; public: + GraphicButton(std::string containerName="", std::string objName=""); void init(int x, int y, int w=defW, int h=defH); + bool getUseCustomTexture() const { return useCustomTexture; } + Texture *getCustomTexture() const { return customTexture; } + + void setUseCustomTexture(bool value) { useCustomTexture=value; } + void setCustomTexture(Texture *value) { customTexture=value; } + bool getLighted() const {return lighted;} void setLighted(bool lighted) {this->lighted= lighted;} diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 139387e72..510171ed5 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -1813,9 +1813,15 @@ void Game::render2d(){ str+= "\n"; str+= "Visible quad area: " + floatToStr(visibleQuad.area()) +"\n"; + int totalUnitcount = 0; + for(int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction= world.getFaction(i); + totalUnitcount += faction->getUnitCount(); + } + VisibleQuadContainerCache &qCache =renderer.getQuadCache(); int visibleUnitCount = qCache.visibleQuadUnitList.size(); - str+= "Visible unit count: " + intToStr(visibleUnitCount) +"\n"; + str+= "Visible unit count: " + intToStr(visibleUnitCount) + " total: " + intToStr(totalUnitcount) + "\n"; int visibleObjectCount = qCache.visibleObjectList.size(); str+= "Visible object count: " + intToStr(visibleObjectCount) +"\n"; diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 52f9bd7f4..c3338f9c8 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -1305,12 +1305,24 @@ void Renderer::renderButton(const GraphicButton *button, const Vec4f *fontColorO //background CoreData &coreData= CoreData::getInstance(); - Texture2D *backTexture= w>3*h/2? coreData.getButtonBigTexture(): coreData.getButtonSmallTexture(); + Texture2D *backTexture = NULL; + + if(button->getUseCustomTexture() == true) { + backTexture = dynamic_cast(button->getCustomTexture()); + } + else { + backTexture = w > 3 * h / 2 ? coreData.getButtonBigTexture(): coreData.getButtonSmallTexture(); + } glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); - glBindTexture(GL_TEXTURE_2D, static_cast(backTexture)->getHandle()); + if(backTexture != NULL) { + glBindTexture(GL_TEXTURE_2D, static_cast(backTexture)->getHandle()); + } + else { + glBindTexture(GL_TEXTURE_2D, 0); + } //button Vec4f fontColor; @@ -1381,8 +1393,7 @@ void Renderer::renderButton(const GraphicButton *button, const Vec4f *fontColorO Vec2i textPos= Vec2i(x+w/2, y+h/2); - if(button->getEditable()){ - + if(button->getEditable()) { renderText( button->getText(), button->getFont(), color, x+w/2, y+h/2, true); @@ -4535,7 +4546,9 @@ void Renderer::renderQuad(int x, int y, int w, int h, const Texture2D *texture) h = texture->getPixmapConst()->getH(); } - glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getHandle()); + if(texture != NULL) { + glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getHandle()); + } Vec2i texCoords[4]; Vec2i vertices[4]; diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index b2c289193..68de3a295 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -2077,7 +2077,8 @@ int32 MenuStateConnectedGame::getNetworkPlayerStatus() { return result; } -void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result, void *userdata) { +void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, pair result, void *userdata) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); Lang &lang= Lang::getInstance(); @@ -2108,7 +2109,7 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client } else if(type == ftp_cct_Map) { getMissingMapFromFTPServerInProgress = false; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] result = %d\n",itemName.c_str(),result); + 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); @@ -2118,7 +2119,7 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client ClientInterface* clientInterface= networkManager.getClientInterface(); const GameSettings *gameSettings = clientInterface->getGameSettings(); - if(result == ftp_crt_SUCCESS) { + if(result.first == ftp_crt_SUCCESS) { // Clear the CRC file Cache Checksum::clearFileCache(); //lastCheckedCRCMapValue = -1; @@ -2148,11 +2149,13 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client sprintf(szMsg,"Player: %s FAILED to download the map: [%s] using CURL version [%s]",getHumanPlayerName().c_str(),gameSettings->getMap().c_str(),curlVersion->version); } clientInterface->sendTextMessage(szMsg,-1, true); + + console.addLine(result.second,true); } } else if(type == ftp_cct_Tileset) { getMissingTilesetFromFTPServerInProgress = false; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] result = %d\n",itemName.c_str(),result); + 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); @@ -2162,7 +2165,7 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client ClientInterface* clientInterface= networkManager.getClientInterface(); const GameSettings *gameSettings = clientInterface->getGameSettings(); - if(result == ftp_crt_SUCCESS) { + if(result.first == ftp_crt_SUCCESS) { char szMsg[1024]=""; if(lang.hasString("DataMissingTilesetSuccessDownload") == true) { sprintf(szMsg,lang.get("DataMissingTilesetSuccessDownload").c_str(),getHumanPlayerName().c_str(),gameSettings->getTileset().c_str()); @@ -2206,11 +2209,12 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client sprintf(szMsg,"Player: %s FAILED to download the tileset: [%s] using CURL version [%s]",getHumanPlayerName().c_str(),gameSettings->getTileset().c_str(),curlVersion->version); } clientInterface->sendTextMessage(szMsg,-1, true); + console.addLine(result.second,true); } } else if(type == ftp_cct_Techtree) { getMissingTechtreeFromFTPServerInProgress = false; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] result = %d\n",itemName.c_str(),result); + 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); @@ -2220,7 +2224,7 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client ClientInterface* clientInterface= networkManager.getClientInterface(); const GameSettings *gameSettings = clientInterface->getGameSettings(); - if(result == ftp_crt_SUCCESS) { + if(result.first == ftp_crt_SUCCESS) { char szMsg[1024]=""; if(lang.hasString("DataMissingTechtreeSuccessDownload") == true) { sprintf(szMsg,lang.get("DataMissingTechtreeSuccessDownload").c_str(),getHumanPlayerName().c_str(),gameSettings->getTech().c_str()); @@ -2264,6 +2268,7 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client sprintf(szMsg,"Player: %s FAILED to download the techtree: [%s] using CURL version [%s]",getHumanPlayerName().c_str(),gameSettings->getTech().c_str(),curlVersion->version); } clientInterface->sendTextMessage(szMsg,-1, true); + console.addLine(result.second,true); } } } diff --git a/source/glest_game/menu/menu_state_connected_game.h b/source/glest_game/menu/menu_state_connected_game.h index a3784bf63..93dff0a6b 100644 --- a/source/glest_game/menu/menu_state_connected_game.h +++ b/source/glest_game/menu/menu_state_connected_game.h @@ -197,7 +197,8 @@ private: void showMessageBox(const string &text, const string &header, bool toggle); void showFTPMessageBox(const string &text, const string &header, bool toggle); - virtual void FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result,void *userdata); + virtual void FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, pair result,void *userdata); int32 getNetworkPlayerStatus(); }; diff --git a/source/glest_game/menu/menu_state_masterserver.cpp b/source/glest_game/menu/menu_state_masterserver.cpp index ae44d919f..c08e48957 100644 --- a/source/glest_game/menu/menu_state_masterserver.cpp +++ b/source/glest_game/menu/menu_state_masterserver.cpp @@ -43,6 +43,8 @@ static const char *IRC_CHANNEL = "#megaglest-lobby"; MenuStateMasterserver::MenuStateMasterserver(Program *program, MainMenu *mainMenu): MenuState(program, mainMenu, "masterserver") { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n\n\n******************** ENTERING MASTERSERVER MENU\n\n\n\n\n"); + containerName = "MasterServer"; updateFromMasterserverThread = NULL; ircClient = NULL; @@ -839,6 +841,9 @@ void MenuStateMasterserver::rebuildServerLines(const string &serverInfo) { Tokenize(serverInfo,serverList,"\n"); for(int i=0; i < serverList.size(); i++) { string &server = serverList[i]; + if(trim(server) == "") { + continue; + } std::vector serverEntities; Tokenize(server,serverEntities,"|"); const int MIN_FIELDS_EXPECTED = 14; diff --git a/source/glest_game/menu/menu_state_mods.cpp b/source/glest_game/menu/menu_state_mods.cpp new file mode 100644 index 000000000..e2529bff1 --- /dev/null +++ b/source/glest_game/menu/menu_state_mods.cpp @@ -0,0 +1,1181 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2011 Mark Vejvoda +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#include "menu_state_mods.h" + +#include "renderer.h" +#include "sound_renderer.h" +#include "core_data.h" +#include "config.h" +#include "menu_state_root.h" +#include "metrics.h" +#include "conversion.h" +#include +#include +#include "cache_manager.h" +#include "leak_dumper.h" + + +namespace Glest{ namespace Game{ + +static const string ITEM_MISSING = "***missing***"; + +using namespace Shared::Util; + +struct FormatString { + void operator()(string &s) { + s = formatString(s); + } +}; + +// ===================================================== +// class MenuStateConnectedGame +// ===================================================== + +MenuStateMods::MenuStateMods(Program *program, MainMenu *mainMenu) : + MenuState(program, mainMenu, "mods") { + + containerName = "Mods"; + Lang &lang= Lang::getInstance(); + Config &config = Config::getInstance(); + + ftpClientThread = NULL; + selectedTechName = ""; + selectedTilesetName = ""; + selectedMapName = ""; + showFullConsole = false; + keyButtonsLineHeight = 20; + keyButtonsHeight = 20; + keyButtonsWidth = 200; + int scrollListsYPos = 700; + //keyButtonsYBase = scrollListsYPos - keyButtonsLineHeight; + keyButtonsYBase = scrollListsYPos; + keyButtonsToRender = 400 / keyButtonsLineHeight; + int labelWidth = 5; + + //create + int techInfoXPos = 10; + keyTechScrollBarTitle1.registerGraphicComponent(containerName,"keyTechScrollBarTitle1"); + keyTechScrollBarTitle1.init(techInfoXPos,scrollListsYPos + 20,labelWidth,20); + keyTechScrollBarTitle1.setText(lang.get("TechTitle1")); + keyTechScrollBarTitle2.registerGraphicComponent(containerName,"keyTechScrollBarTitle2"); + keyTechScrollBarTitle2.init(techInfoXPos + 200,scrollListsYPos + 20,labelWidth,20); + keyTechScrollBarTitle2.setText(lang.get("TechTitle2")); + + int mapInfoXPos = 270; + keyMapScrollBarTitle1.registerGraphicComponent(containerName,"keyMapScrollBarTitle1"); + keyMapScrollBarTitle1.init(mapInfoXPos,scrollListsYPos + 20,labelWidth,20); + keyMapScrollBarTitle1.setText(lang.get("MapTitle1")); + keyMapScrollBarTitle2.registerGraphicComponent(containerName,"keyMapScrollBarTitle2"); + keyMapScrollBarTitle2.init(mapInfoXPos + 200,scrollListsYPos + 20,labelWidth,20); + keyMapScrollBarTitle2.setText(lang.get("MapTitle2")); + + int tilesetInfoXPos = 530; + keyTilesetScrollBarTitle1.registerGraphicComponent(containerName,"keyTilesetScrollBarTitle1"); + keyTilesetScrollBarTitle1.init(tilesetInfoXPos,scrollListsYPos + 20,labelWidth,20); + keyTilesetScrollBarTitle1.setText(lang.get("TilesetTitle1")); + + mainMessageBoxState = ftpmsg_None; + mainMessageBox.registerGraphicComponent(containerName,"mainMessageBox"); + mainMessageBox.init(lang.get("Yes"),lang.get("No")); + mainMessageBox.setEnabled(false); + + buttonReturn.registerGraphicComponent(containerName,"buttonReturn"); + buttonReturn.init(450, 140, 125); + buttonReturn.setText(lang.get("Return")); + + int installButtonYPos = 280; + buttonInstallTech.registerGraphicComponent(containerName,"buttonInstallTech"); + buttonInstallTech.init(techInfoXPos + 40, installButtonYPos, 125); + buttonInstallTech.setText(lang.get("Install")); + buttonRemoveTech.registerGraphicComponent(containerName,"buttonRemoveTech"); + buttonRemoveTech.init(techInfoXPos + 40, installButtonYPos-30, 125); + buttonRemoveTech.setText(lang.get("Remove")); + + buttonInstallTileset.registerGraphicComponent(containerName,"buttonInstallTileset"); + buttonInstallTileset.init(tilesetInfoXPos + 20, installButtonYPos, 125); + buttonInstallTileset.setText(lang.get("Install")); + buttonRemoveTileset.registerGraphicComponent(containerName,"buttonRemoveTileset"); + buttonRemoveTileset.init(tilesetInfoXPos + 20, installButtonYPos-30, 125); + buttonRemoveTileset.setText(lang.get("Remove")); + + buttonInstallMap.registerGraphicComponent(containerName,"buttonInstallMap"); + buttonInstallMap.init(mapInfoXPos + 40, installButtonYPos, 125); + buttonInstallMap.setText(lang.get("Install")); + buttonRemoveMap.registerGraphicComponent(containerName,"buttonRemoveMap"); + buttonRemoveMap.init(mapInfoXPos + 40, installButtonYPos-30, 125); + buttonRemoveMap.setText(lang.get("Remove")); + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + CURL *handle = SystemFlags::initHTTP(); + std::string techsMetaData = SystemFlags::getHTTP("http://localhost/glest/showTechsForGlest.php",handle); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("techsMetaData [%s]\n",techsMetaData.c_str()); + std::string tilesetsMetaData = SystemFlags::getHTTP("http://localhost/glest/showTilesetsForGlest.php",handle); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("tilesetsMetaData [%s]\n",tilesetsMetaData.c_str()); + std::string mapsMetaData = SystemFlags::getHTTP("http://localhost/glest/showMapsForGlest.php",handle); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("mapsMetaData [%s]\n",mapsMetaData.c_str()); + SystemFlags::cleanupHTTP(&handle); + + tilesetListRemote.clear(); + Tokenize(tilesetsMetaData,tilesetListRemote,"\n"); + + getTilesetsLocalList(); + for(int i=0; i < tilesetListRemote.size(); i++) { + string tilesetInfo = tilesetListRemote[i]; + std::vector tilesetInfoList; + Tokenize(tilesetInfo,tilesetInfoList,"|"); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("tilesetInfoList.size() [%d]\n",(int)tilesetInfoList.size()); + if(tilesetInfoList.size() >= 4) { + string tilesetName = tilesetInfoList[0]; + string tilesetCRC = tilesetInfoList[1]; + string tilesetDescription = tilesetInfoList[2]; + string tilesetURL = tilesetInfoList[3]; + //bool alreadyHasTileset = (std::find(tilesetFiles.begin(),tilesetFiles.end(),tilesetName) != tilesetFiles.end()); + tilesetCacheList[tilesetName] = tilesetURL; + + GraphicButton *button=new GraphicButton(); + button->init(tilesetInfoXPos, keyButtonsYBase, keyButtonsWidth,keyButtonsHeight); + button->setText(tilesetName); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance().getCustomTexture()); + + //if(alreadyHasTileset == true) { + // button->setEnabled(false); + //} + keyTilesetButtons.push_back(button); + } + } + + techListRemote.clear(); + Tokenize(techsMetaData,techListRemote,"\n"); + + getTechsLocalList(); + for(int i=0; i < techListRemote.size(); i++) { + string techInfo = techListRemote[i]; + std::vector techInfoList; + Tokenize(techInfo,techInfoList,"|"); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("techInfoList.size() [%d]\n",(int)techInfoList.size()); + if(techInfoList.size() >= 5) { + string techName = techInfoList[0]; + string techFactionCount = techInfoList[1]; + string techCRC = techInfoList[2]; + string techDescription = techInfoList[3]; + string techURL = techInfoList[4]; + //bool alreadyHasTech = (std::find(techTreeFiles.begin(),techTreeFiles.end(),techName) != techTreeFiles.end()); + techCacheList[techName] = techURL; + + GraphicButton *button=new GraphicButton(); + button->init(techInfoXPos, keyButtonsYBase, keyButtonsWidth,keyButtonsHeight); + button->setText(techName); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance().getCustomTexture()); + + //if(alreadyHasTech == true) { + // button->setEnabled(false); + //} + keyTechButtons.push_back(button); + GraphicLabel *label=new GraphicLabel(); + label->init(techInfoXPos + keyButtonsWidth+10,keyButtonsYBase,labelWidth,20); + label->setText(techFactionCount); + labelsTech.push_back(label); + } + } + + mapListRemote.clear(); + Tokenize(mapsMetaData,mapListRemote,"\n"); + + getMapsLocalList(); + for(int i=0; i < mapListRemote.size(); i++) { + string mapInfo = mapListRemote[i]; + std::vector mapInfoList; + Tokenize(mapInfo,mapInfoList,"|"); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("mapInfoList.size() [%d]\n",(int)mapInfoList.size()); + if(mapInfoList.size() >= 5) { + string mapName = mapInfoList[0]; + string mapPlayerCount = mapInfoList[1]; + string mapCRC = mapInfoList[2]; + string mapDescription = mapInfoList[3]; + string mapURL = mapInfoList[4]; + //bool alreadyHasMap = (std::find(mapFiles.begin(),mapFiles.end(),mapName) != mapFiles.end()); + mapCacheList[mapName] = mapURL; + + GraphicButton *button=new GraphicButton(); + button->init(mapInfoXPos, keyButtonsYBase, keyButtonsWidth,keyButtonsHeight); + button->setText(mapName); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance().getCustomTexture()); + + //if(alreadyHasMap == true) { + // button->setEnabled(false); + //} + keyMapButtons.push_back(button); + GraphicLabel *label=new GraphicLabel(); + label->init(mapInfoXPos + keyButtonsWidth + 10,keyButtonsYBase,labelWidth,20); + label->setText(mapPlayerCount); + labelsMap.push_back(label); + } + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + int listBoxLength = 400; + keyTilesetScrollBar.init(tilesetInfoXPos + keyButtonsWidth,scrollListsYPos-listBoxLength+keyButtonsLineHeight,false,200,20); + keyTilesetScrollBar.setLength(listBoxLength); + keyTilesetScrollBar.setElementCount(keyTilesetButtons.size()); + keyTilesetScrollBar.setVisibleSize(keyButtonsToRender); + keyTilesetScrollBar.setVisibleStart(0); + + keyTechScrollBar.init(techInfoXPos + keyButtonsWidth + labelWidth + 20,scrollListsYPos-listBoxLength+keyButtonsLineHeight,false,200,20); + keyTechScrollBar.setLength(listBoxLength); + keyTechScrollBar.setElementCount(keyTechButtons.size()); + keyTechScrollBar.setVisibleSize(keyButtonsToRender); + keyTechScrollBar.setVisibleStart(0); + + keyMapScrollBar.init(mapInfoXPos + keyButtonsWidth + labelWidth + 20,scrollListsYPos-listBoxLength+keyButtonsLineHeight,false,200,20); + keyMapScrollBar.setLength(listBoxLength); + keyMapScrollBar.setElementCount(keyMapButtons.size()); + keyMapScrollBar.setVisibleSize(keyButtonsToRender); + keyMapScrollBar.setVisibleStart(0); + + GraphicComponent::applyAllCustomProperties(containerName); + + findDirs(config.getPathListForType(ptTilesets), tilesetFiles); + findDirs(config.getPathListForType(ptTechs), techTreeFiles); + + vector mapPathList = config.getPathListForType(ptMaps); + std::pair mapsPath; + if(mapPathList.size() > 0) { + mapsPath.first = mapPathList[0]; + } + if(mapPathList.size() > 1) { + mapsPath.second = mapPathList[1]; + } + std::pair tilesetsPath; + vector tilesetsList = Config::getInstance().getPathListForType(ptTilesets); + if(tilesetsList.size() > 0) { + tilesetsPath.first = tilesetsList[0]; + if(tilesetsList.size() > 1) { + tilesetsPath.second = tilesetsList[1]; + } + } + + std::pair techtreesPath; + vector techtreesList = Config::getInstance().getPathListForType(ptTechs); + if(techtreesList.size() > 0) { + techtreesPath.first = techtreesList[0]; + if(techtreesList.size() > 1) { + techtreesPath.second = techtreesList[1]; + } + } + + string fileArchiveExtension = config.getString("FileArchiveExtension",""); + string fileArchiveExtractCommand = config.getString("FileArchiveExtractCommand",""); + string fileArchiveExtractCommandParameters = config.getString("FileArchiveExtractCommandParameters",""); + + ftpClientThread = new FTPClientThread(-1,"", + mapsPath,tilesetsPath,techtreesPath, + this,fileArchiveExtension,fileArchiveExtractCommand, + fileArchiveExtractCommandParameters); + ftpClientThread->start(); + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void MenuStateMods::getTechsLocalList() { + Config &config = Config::getInstance(); + vector results; + findDirs(config.getPathListForType(ptTechs), results); + techTreeFiles = results; +} + +void MenuStateMods::refreshTechs() { + getTechsLocalList(); + for(int i=0; i < techListRemote.size(); i++) { + string techInfo = techListRemote[i]; + std::vector techInfoList; + Tokenize(techInfo,techInfoList,"|"); + if(techInfoList.size() >= 5) { + string techName = techInfoList[0]; + string techFactionCount = techInfoList[1]; + string techCRC = techInfoList[2]; + string techDescription = techInfoList[3]; + string techURL = techInfoList[4]; + //bool alreadyHasTech = (std::find(techTreeFiles.begin(),techTreeFiles.end(),techName) != techTreeFiles.end()); + techCacheList[techName] = techURL; + + //GraphicButton *button= keyTechButtons[i]; + //if(alreadyHasTech == true) { + // button->setEnabled(false); + //} + } + } +} + +void MenuStateMods::getTilesetsLocalList() { + Config &config = Config::getInstance(); + vector results; + findDirs(config.getPathListForType(ptTilesets), results); + tilesetFiles = results; +} + +void MenuStateMods::refreshTilesets() { + getTilesetsLocalList(); + for(int i=0; i < tilesetListRemote.size(); i++) { + string tilesetInfo = tilesetListRemote[i]; + std::vector tilesetInfoList; + Tokenize(tilesetInfo,tilesetInfoList,"|"); + if(tilesetInfoList.size() >= 4) { + string tilesetName = tilesetInfoList[0]; + string tilesetCRC = tilesetInfoList[1]; + string tilesetDescription = tilesetInfoList[2]; + string tilesetURL = tilesetInfoList[3]; + //bool alreadyHasTileset = (std::find(tilesetFiles.begin(),tilesetFiles.end(),tilesetName) != tilesetFiles.end()); + tilesetCacheList[tilesetName] = tilesetURL; + + //GraphicButton *button= keyTilesetButtons[i]; + //if(alreadyHasTileset == true) { + // button->setEnabled(false); + //} + } + } +} + +void MenuStateMods::getMapsLocalList() { + Config &config = Config::getInstance(); + vector results; + set allMaps; + findAll(config.getPathListForType(ptMaps), "*.gbm", results, false, false); + copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); + results.clear(); + findAll(config.getPathListForType(ptMaps), "*.mgm", results, false, false); + copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); + results.clear(); + + copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); + mapFiles = results; +} + +void MenuStateMods::refreshMaps() { + getMapsLocalList(); + for(int i=0; i < mapListRemote.size(); i++) { + string mapInfo = mapListRemote[i]; + std::vector mapInfoList; + Tokenize(mapInfo,mapInfoList,"|"); + if(mapInfoList.size() >= 5) { + string mapName = mapInfoList[0]; + string mapPlayerCount = mapInfoList[1]; + string mapCRC = mapInfoList[2]; + string mapDescription = mapInfoList[3]; + string mapURL = mapInfoList[4]; + //bool alreadyHasMap = (std::find(mapFiles.begin(),mapFiles.end(),mapName) != mapFiles.end()); + mapCacheList[mapName] = mapURL; + + //GraphicButton *button= keyMapButtons[i]; + //if(alreadyHasMap == true) { + // button->setEnabled(false); + //} + } + } +} + +MenuStateMods::~MenuStateMods() { + clearUserButtons(); + + if(ftpClientThread != NULL) { + ftpClientThread->setCallBackObject(NULL); + if(ftpClientThread->shutdownAndWait() == true) { + delete ftpClientThread; + ftpClientThread = NULL; + } + } +} + +void MenuStateMods::clearUserButtons() { + // Techs + while(!keyTechButtons.empty()) { + delete keyTechButtons.back(); + keyTechButtons.pop_back(); + } + while(!labelsTech.empty()) { + delete labelsTech.back(); + labelsTech.pop_back(); + } + + // Tilesets + while(!keyTilesetButtons.empty()) { + delete keyTilesetButtons.back(); + keyTilesetButtons.pop_back(); + } + + // Maps + while(!keyMapButtons.empty()) { + delete keyMapButtons.back(); + keyMapButtons.pop_back(); + } + while(!labelsMap.empty()) { + delete labelsMap.back(); + labelsMap.pop_back(); + } +} + +void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { + + CoreData &coreData= CoreData::getInstance(); + SoundRenderer &soundRenderer= SoundRenderer::getInstance(); + Lang &lang= Lang::getInstance(); + + if(buttonReturn.mouseClick(x,y)) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + soundRenderer.playFx(coreData.getClickSoundA()); + + if(fileFTPProgressList.size() > 0) { + mainMessageBoxState = ftpmsg_Quit; + mainMessageBox.init(lang.get("Yes"),lang.get("No")); + showMessageBox("You currently have: " + intToStr(fileFTPProgressList.size()) + " files downloading, exit and abort these file(s)?", "Question?", true); + } + else { + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + return; + } + } + else if(mainMessageBox.getEnabled()) { + int button= 1; + if(mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMessageBox.setEnabled(false); + mainMessageBox.init(lang.get("Yes"),lang.get("No")); + if(button == 1) { + if(mainMessageBoxState == ftpmsg_Quit) { + mainMessageBoxState = ftpmsg_None; + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + return; + } + else if(mainMessageBoxState == ftpmsg_GetMap) { + mainMessageBoxState = ftpmsg_None; + + Config &config = Config::getInstance(); + vector mapPaths = config.getPathListForType(ptMaps); + if(mapPaths.size() > 1) { + string removeMap = mapPaths[1]; + endPathWithSlash(removeMap); + removeMap += selectedMapName; + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Removing Map [%s]\n",removeMap.c_str()); + removeFile(removeMap); + selectedMapName = ""; + refreshMaps(); + Checksum::clearFileCache(); + } + } + else if(mainMessageBoxState == ftpmsg_GetTileset) { + mainMessageBoxState = ftpmsg_None; + + Config &config = Config::getInstance(); + vector tilesetPaths = config.getPathListForType(ptTilesets); + if(tilesetPaths.size() > 1) { + string removeTileset = tilesetPaths[1]; + endPathWithSlash(removeTileset); + removeTileset += selectedTilesetName; + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Removing Tileset [%s]\n",removeTileset.c_str()); + removeFolder(removeTileset); + + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + safeMutexFTPProgress.Lock(); + Checksum::clearFileCache(); + vector paths = Config::getInstance().getPathListForType(ptTilesets); + string pathSearchString = string("/") + selectedTilesetName + string("/*"); + const string filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, filterFileExt); + safeMutexFTPProgress.ReleaseLock(); + + selectedTilesetName = ""; + refreshTilesets(); + } + } + else if(mainMessageBoxState == ftpmsg_GetTechtree) { + mainMessageBoxState = ftpmsg_None; + + Config &config = Config::getInstance(); + vector techPaths = config.getPathListForType(ptTechs); + if(techPaths.size() > 1) { + string removeTech = techPaths[1]; + endPathWithSlash(removeTech); + removeTech+= selectedTechName; + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Removing Techtree [%s]\n",removeTech.c_str()); + removeFolder(removeTech); + + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + // Clear the CRC file Cache + safeMutexFTPProgress.Lock(); + Checksum::clearFileCache(); + vector paths = Config::getInstance().getPathListForType(ptTechs); + string pathSearchString = string("/") + selectedTechName + string("/*"); + const string filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, filterFileExt); + safeMutexFTPProgress.ReleaseLock(); + + selectedTechName = ""; + refreshTechs(); + } + } + } + } + } + else if(keyTechScrollBar.mouseClick(x, y)) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + soundRenderer.playFx(coreData.getClickSoundB()); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + else if(keyTilesetScrollBar.mouseClick(x, y)) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + soundRenderer.playFx(coreData.getClickSoundB()); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + else if(keyMapScrollBar.mouseClick(x, y)) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + soundRenderer.playFx(coreData.getClickSoundB()); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + else if(buttonInstallTech.mouseClick(x, y) && buttonInstallTech.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if(selectedTechName != "") { + bool alreadyHasTech = (std::find(techTreeFiles.begin(),techTreeFiles.end(),selectedTechName) != techTreeFiles.end()); + if(alreadyHasTech == true) { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You already have the tech: " + selectedTechName + " installed.", "Notice", true); + } + else { + string techName = selectedTechName; + string techURL = techCacheList[techName]; + ftpClientThread->addTechtreeToRequests(techName,techURL); + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + fileFTPProgressList[techName] = pair(0,""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallTech.setEnabled(false); + } + } + else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You must first select a tech to install.", "Notice", true); + } + } + else if(buttonRemoveTech.mouseClick(x, y) && buttonRemoveTech.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if(selectedTechName != "") { + bool alreadyHasTech = (std::find(techTreeFiles.begin(),techTreeFiles.end(),selectedTechName) != techTreeFiles.end()); + if(alreadyHasTech == true) { + mainMessageBoxState = ftpmsg_GetTechtree; + showMessageBox("Are you sure you want to remove the tech: " + selectedTechName, "Question?", true); + } + else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You do not have the tech: " + selectedTechName + " installed.", "Notice", true); + } + } + else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You must first select a tech to remove.", "Notice", true); + } + } + else if(buttonInstallTileset.mouseClick(x, y) && buttonInstallTileset.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if(selectedTilesetName != "") { + bool alreadyHasTileset = (std::find(tilesetFiles.begin(),tilesetFiles.end(),selectedTilesetName) != tilesetFiles.end()); + if(alreadyHasTileset == true) { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You already have the tileset: " + selectedTilesetName + " installed.", "Notice", true); + } + else { + string tilesetName = selectedTilesetName; + string tilesetURL = tilesetCacheList[tilesetName]; + ftpClientThread->addTilesetToRequests(tilesetName,tilesetURL); + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + fileFTPProgressList[tilesetName] = pair(0,""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallTileset.setEnabled(false); + } + } + else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You must first select a tileset to install.", "Notice", true); + } + } + else if(buttonRemoveTileset.mouseClick(x, y) && buttonRemoveTileset.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if(selectedTilesetName != "") { + bool alreadyHasTileset = (std::find(tilesetFiles.begin(),tilesetFiles.end(),selectedTilesetName) != tilesetFiles.end()); + if(alreadyHasTileset == true) { + mainMessageBoxState = ftpmsg_GetTileset; + showMessageBox("Are you sure you want to remove the tileset: " + selectedTilesetName, "Question?", true); + } + else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You do not have the tileset: " + selectedTilesetName + " installed.", "Notice", true); + } + } + else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You must first select a tileset to remove.", "Notice", true); + } + } + else if(buttonInstallMap.mouseClick(x, y) && buttonInstallMap.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if(selectedMapName != "") { + bool alreadyHasMap = (std::find(mapFiles.begin(),mapFiles.end(),selectedMapName) != mapFiles.end()); + if(alreadyHasMap == true) { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You already have the map: " + selectedMapName + " installed.", "Notice", true); + } + else { + string mapName = selectedMapName; + string mapURL = mapCacheList[mapName]; + ftpClientThread->addMapToRequests(mapName,mapURL); + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + fileFTPProgressList[mapName] = pair(0,""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallMap.setEnabled(false); + } + } + else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You must first select a map to install.", "Notice", true); + } + } + else if(buttonRemoveMap.mouseClick(x, y) && buttonRemoveMap.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if(selectedMapName != "") { + bool alreadyHasMap = (std::find(mapFiles.begin(),mapFiles.end(),selectedMapName) != mapFiles.end()); + if(alreadyHasMap == true) { + mainMessageBoxState = ftpmsg_GetMap; + showMessageBox("Are you sure you want to remove the map: " + selectedMapName, "Question?", true); + } + else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You do not have the map: " + selectedMapName + " installed.", "Notice", true); + } + } + else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.get("Ok")); + showMessageBox("You must first select a map to remove.", "Notice", true); + } + } + else { + if(keyMapScrollBar.getElementCount() != 0) { + for (int i = keyMapScrollBar.getVisibleStart(); i + <= keyMapScrollBar.getVisibleEnd(); ++i) { + if(keyMapButtons[i]->mouseClick(x, y) && keyMapButtons[i]->getEnabled()) { + string mapName = keyMapButtons[i]->getText(); + if(mapName != "") { + //string mapURL = mapCacheList[mapName]; + //ftpClientThread->addMapToRequests(mapName,mapURL); + //MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + //fileFTPProgressList[mapName] = pair(0,""); + //safeMutexFTPProgress.ReleaseLock(); + selectedMapName = mapName; + //bool alreadyHasMap = (std::find(mapFiles.begin(),mapFiles.end(),selectedMapName) != mapFiles.end()); + //buttonInstallMap.setEnabled(alreadyHasMap == false); + //buttonRemoveMap.setEnabled(alreadyHasMap); + } + + break; + } + } + } + if(keyTechScrollBar.getElementCount() != 0) { + for (int i = keyTechScrollBar.getVisibleStart(); i + <= keyTechScrollBar.getVisibleEnd(); ++i) { + if(keyTechButtons[i]->mouseClick(x, y) && keyTechButtons[i]->getEnabled()) { + string techName = keyTechButtons[i]->getText(); + if(techName != "") { + //string techURL = techCacheList[techName]; + //ftpClientThread->addTechtreeToRequests(techName,techURL); + //MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + //fileFTPProgressList[techName] = pair(0,""); + //safeMutexFTPProgress.ReleaseLock(); + selectedTechName = techName; + + //bool alreadyHasTech = (std::find(techTreeFiles.begin(),techTreeFiles.end(),selectedTechName) != techTreeFiles.end()); + //buttonInstallTech.setEnabled(alreadyHasTech == false); + //buttonRemoveTech.setEnabled(alreadyHasTech); + } + + break; + } + } + } + if(keyTilesetScrollBar.getElementCount() != 0) { + for (int i = keyTilesetScrollBar.getVisibleStart(); i + <= keyTilesetScrollBar.getVisibleEnd(); ++i) { + if(keyTilesetButtons[i]->mouseClick(x, y) && keyTilesetButtons[i]->getEnabled()) { + string tilesetName = keyTilesetButtons[i]->getText(); + if(tilesetName != "") { + //string tilesetURL = tilesetCacheList[tilesetName]; + //ftpClientThread->addTilesetToRequests(tilesetName,tilesetURL); + //MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + //fileFTPProgressList[tilesetName] = pair(0,""); + //safeMutexFTPProgress.ReleaseLock(); + selectedTilesetName = tilesetName; + //bool alreadyHasTileset = (std::find(tilesetFiles.begin(),tilesetFiles.end(),selectedTilesetName) != tilesetFiles.end()); + //buttonInstallTileset.setEnabled(alreadyHasTileset == false); + //buttonRemoveTileset.setEnabled(alreadyHasTileset); + } + break; + } + } + } + } + + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void MenuStateMods::mouseMove(int x, int y, const MouseState *ms) { + buttonReturn.mouseMove(x, y); + + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + + buttonInstallTech.mouseMove(x, y); + buttonRemoveTech.mouseMove(x, y); + buttonInstallTileset.mouseMove(x, y); + buttonRemoveTileset.mouseMove(x, y); + buttonInstallMap.mouseMove(x, y); + buttonRemoveMap.mouseMove(x, y); + + if (ms->get(mbLeft)) { + keyMapScrollBar.mouseDown(x, y); + keyTechScrollBar.mouseDown(x, y); + keyTilesetScrollBar.mouseDown(x, y); + } + else { + keyMapScrollBar.mouseMove(x, y); + keyTechScrollBar.mouseMove(x, y); + keyTilesetScrollBar.mouseMove(x, y); + } + + if(keyMapScrollBar.getElementCount() !=0) { + for(int i = keyMapScrollBar.getVisibleStart(); i <= keyMapScrollBar.getVisibleEnd(); ++i) { + keyMapButtons[i]->mouseMove(x, y); + } + } + if(keyTechScrollBar.getElementCount() !=0) { + for(int i = keyTechScrollBar.getVisibleStart(); i <= keyTechScrollBar.getVisibleEnd(); ++i) { + keyTechButtons[i]->mouseMove(x, y); + } + } + if(keyTilesetScrollBar.getElementCount() !=0) { + for(int i = keyTilesetScrollBar.getVisibleStart(); i <= keyTilesetScrollBar.getVisibleEnd(); ++i) { + keyTilesetButtons[i]->mouseMove(x, y); + } + } +} + +void MenuStateMods::render() { + try { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + Renderer &renderer= Renderer::getInstance(); + + renderer.renderButton(&buttonReturn); + renderer.renderButton(&buttonInstallTech); + renderer.renderButton(&buttonRemoveTech); + renderer.renderButton(&buttonInstallTileset); + renderer.renderButton(&buttonRemoveTileset); + renderer.renderButton(&buttonInstallMap); + renderer.renderButton(&buttonRemoveMap); + + //renderer.renderTextureQuad(300,200,200,400,NULL,0.5); + + // Render Tech List + renderer.renderLabel(&keyTechScrollBarTitle1); + renderer.renderLabel(&keyTechScrollBarTitle2); + if(keyTechScrollBar.getElementCount() != 0) { + for(int i = keyTechScrollBar.getVisibleStart(); + i <= keyTechScrollBar.getVisibleEnd(); ++i) { + bool alreadyHasTech = (std::find(techTreeFiles.begin(),techTreeFiles.end(),keyTechButtons[i]->getText()) != techTreeFiles.end()); + if(alreadyHasTech == true) { + Vec4f buttonColor = CYAN; + buttonColor.w = 0.7f; + renderer.renderButton(keyTechButtons[i],&buttonColor); + } + else if(keyTechButtons[i]->getText() == selectedTechName) { + renderer.renderButton(keyTechButtons[i],&YELLOW); + } + else { + Vec4f fontColor=Vec4f(1.f, 1.f, 1.f, 0.7f); + renderer.renderButton(keyTechButtons[i],&fontColor); + } + renderer.renderLabel(labelsTech[i]); + } + } + renderer.renderScrollBar(&keyTechScrollBar); + + // Render Tileset List + renderer.renderLabel(&keyTilesetScrollBarTitle1); + if(keyTilesetScrollBar.getElementCount() != 0) { + for(int i = keyTilesetScrollBar.getVisibleStart(); + i <= keyTilesetScrollBar.getVisibleEnd(); ++i) { + bool alreadyHasTileset = (std::find(tilesetFiles.begin(),tilesetFiles.end(),keyTilesetButtons[i]->getText()) != tilesetFiles.end()); + if(alreadyHasTileset == true) { + Vec4f buttonColor = CYAN; + buttonColor.w = 0.7f; + renderer.renderButton(keyTilesetButtons[i],&buttonColor); + } + else if(keyTilesetButtons[i]->getText() == selectedTilesetName) { + renderer.renderButton(keyTilesetButtons[i],&YELLOW); + } + else { + Vec4f fontColor=Vec4f(1.f, 1.f, 1.f, 0.7f); + renderer.renderButton(keyTilesetButtons[i],&fontColor); + } + } + } + renderer.renderScrollBar(&keyTilesetScrollBar); + + // Render Map list + renderer.renderLabel(&keyMapScrollBarTitle1); + renderer.renderLabel(&keyMapScrollBarTitle2); + if(keyMapScrollBar.getElementCount() != 0) { + for(int i = keyMapScrollBar.getVisibleStart(); + i <= keyMapScrollBar.getVisibleEnd(); ++i) { + bool alreadyHasMap = (std::find(mapFiles.begin(),mapFiles.end(),keyMapButtons[i]->getText()) != mapFiles.end()); + if(alreadyHasMap == true) { + Vec4f buttonColor = CYAN; + buttonColor.w = 0.7f; + renderer.renderButton(keyMapButtons[i],&buttonColor); + } + else if(keyMapButtons[i]->getText() == selectedMapName) { + renderer.renderButton(keyMapButtons[i],&YELLOW); + } + else { + Vec4f fontColor=Vec4f(1.f, 1.f, 1.f, 0.7f); + renderer.renderButton(keyMapButtons[i],&fontColor); + } + renderer.renderLabel(labelsMap[i]); + } + } + renderer.renderScrollBar(&keyMapScrollBar); + + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + if(fileFTPProgressList.size() > 0) { + int yLocation = buttonReturn.getY(); + for(std::map >::iterator iterMap = fileFTPProgressList.begin(); + iterMap != fileFTPProgressList.end(); ++iterMap) { + + string progressLabelPrefix = "Downloading " + iterMap->first + " [" + iterMap->second.second + "] "; + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nRendering file progress with the following prefix [%s]\n",progressLabelPrefix.c_str()); + + renderer.renderProgressBar( + iterMap->second.first, + 10, + yLocation, + CoreData::getInstance().getDisplayFontSmall(), + 350,progressLabelPrefix); + + yLocation -= 10; + } + } + safeMutexFTPProgress.ReleaseLock(); + + renderer.renderConsole(&console,showFullConsole,true); + + if(mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } + } + catch(const std::exception &ex) { + char szBuf[1024]=""; + sprintf(szBuf,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + throw runtime_error(szBuf); + } +} + +void MenuStateMods::update() { + Chrono chrono; + chrono.start(); + + Lang &lang= Lang::getInstance(); + + // Tech List + if (keyTechScrollBar.getElementCount() != 0) { + for (int i = keyTechScrollBar.getVisibleStart(); i + <= keyTechScrollBar.getVisibleEnd(); ++i) { + keyTechButtons[i]->setY(keyButtonsYBase - keyButtonsLineHeight * (i + - keyTechScrollBar.getVisibleStart())); + labelsTech[i]->setY(keyButtonsYBase - keyButtonsLineHeight * (i + - keyTechScrollBar.getVisibleStart())); + } + } + + // Tech List + if (keyTilesetScrollBar.getElementCount() != 0) { + for (int i = keyTilesetScrollBar.getVisibleStart(); i + <= keyTilesetScrollBar.getVisibleEnd(); ++i) { + keyTilesetButtons[i]->setY(keyButtonsYBase - keyButtonsLineHeight * (i + - keyTilesetScrollBar.getVisibleStart())); + labelsTech[i]->setY(keyButtonsYBase - keyButtonsLineHeight * (i + - keyTilesetScrollBar.getVisibleStart())); + } + } + + // Map List + if (keyMapScrollBar.getElementCount() != 0) { + for (int i = keyMapScrollBar.getVisibleStart(); i + <= keyMapScrollBar.getVisibleEnd(); ++i) { + keyMapButtons[i]->setY(keyButtonsYBase - keyButtonsLineHeight * (i + - keyMapScrollBar.getVisibleStart())); + labelsMap[i]->setY(keyButtonsYBase - keyButtonsLineHeight * (i + - keyMapScrollBar.getVisibleStart())); + } + } + + console.update(); +} + +void MenuStateMods::keyDown(char key) { + Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); + if(key == configKeys.getCharKey("ShowFullConsole")) { + showFullConsole= true; + } +} + +void MenuStateMods::keyPress(char c) { +} + +void MenuStateMods::keyUp(char key) { + Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); + if(key== configKeys.getCharKey("ShowFullConsole")) { + showFullConsole= false; + } +} + +void MenuStateMods::showMessageBox(const string &text, const string &header, bool toggle) { + if(!toggle){ + mainMessageBox.setEnabled(false); + } + + if(!mainMessageBox.getEnabled()){ + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } + else{ + mainMessageBox.setEnabled(false); + } +} + +void MenuStateMods::FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, pair result,void *userdata) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + Lang &lang= Lang::getInstance(); + if(type == ftp_cct_DownloadProgress) { + FTPClientCallbackInterface::FtpProgressStats *stats = (FTPClientCallbackInterface::FtpProgressStats *)userdata; + if(stats != NULL) { + int fileProgress = 0; + if(stats->download_total > 0) { + fileProgress = ((stats->download_now / stats->download_total) * 100.0); + } + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] current file [%s] fileProgress = %d [now = %f, total = %f]\n",itemName.c_str(),stats->currentFilename.c_str(), fileProgress,stats->download_now,stats->download_total); + + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + pair lastProgress = fileFTPProgressList[itemName]; + fileFTPProgressList[itemName] = pair(fileProgress,stats->currentFilename); + safeMutexFTPProgress.ReleaseLock(); + } + } + 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()); + + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(); + selectedMapName = ""; + buttonInstallMap.setEnabled(true); + + if(result.first == ftp_crt_SUCCESS) { + refreshMaps(); + + // Clear the CRC file Cache + Checksum::clearFileCache(); + //lastCheckedCRCMapValue = -1; + Checksum checksum; + string file = Map::getMapPath(itemName,"",false); + //console.addLine("Checking map CRC [" + file + "]"); + checksum.addFile(file); + uint32 CRCMapValue = checksum.getSum(); + + char szMsg[1024]=""; +// if(lang.hasString("DataMissingMapSuccessDownload") == true) { +// sprintf(szMsg,lang.get("DataMissingMapSuccessDownload").c_str(),getHumanPlayerName().c_str(),gameSettings->getMap().c_str()); +// } +// else { + sprintf(szMsg,"SUCCESSFULLY downloaded the map: %s",itemName.c_str()); +// } + //clientInterface->sendTextMessage(szMsg,-1, true); + console.addLine(szMsg,true); + } + else { + curl_version_info_data *curlVersion= curl_version_info(CURLVERSION_NOW); + + char szMsg[1024]=""; +// if(lang.hasString("DataMissingMapFailDownload") == true) { +// sprintf(szMsg,lang.get("DataMissingMapFailDownload").c_str(),getHumanPlayerName().c_str(),gameSettings->getMap().c_str(),curlVersion->version); +// } +// else { + sprintf(szMsg,"FAILED to download the map: [%s] using CURL version [%s] [%s]",itemName.c_str(),curlVersion->version,result.second.c_str()); +// } + //clientInterface->sendTextMessage(szMsg,-1, true); + console.addLine(szMsg,true); + } + } + else if(type == ftp_cct_Tileset) { + 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(true); + + selectedTilesetName = ""; + buttonInstallTileset.setEnabled(true); + + if(result.first == ftp_crt_SUCCESS) { + refreshTilesets(); + + char szMsg[1024]=""; +// if(lang.hasString("DataMissingTilesetSuccessDownload") == true) { +// sprintf(szMsg,lang.get("DataMissingTilesetSuccessDownload").c_str(),getHumanPlayerName().c_str(),gameSettings->getTileset().c_str()); +// } +// else { + sprintf(szMsg,"SUCCESSFULLY downloaded the tileset: %s",itemName.c_str()); +// } + console.addLine(szMsg,true); + + // START + // Clear the CRC Cache if it is populated + // + // Clear the CRC file Cache + safeMutexFTPProgress.Lock(); + Checksum::clearFileCache(); + + vector paths = Config::getInstance().getPathListForType(ptTilesets); + string pathSearchString = string("/") + itemName + string("/*"); + const string filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, filterFileExt); + + // Refresh CRC + Config &config = Config::getInstance(); + uint32 CRCTilesetValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + itemName + string("/*"), ".xml", NULL); + + safeMutexFTPProgress.ReleaseLock(); + // END + + // Reload tilesets for the UI + //findDirs(Config::getInstance().getPathListForType(ptTilesets), tilesetFiles); + } + else { + curl_version_info_data *curlVersion= curl_version_info(CURLVERSION_NOW); + + char szMsg[1024]=""; +// if(lang.hasString("DataMissingTilesetFailDownload") == true) { +// sprintf(szMsg,lang.get("DataMissingTilesetFailDownload").c_str(),getHumanPlayerName().c_str(),gameSettings->getTileset().c_str(),curlVersion->version); +// } +// else { + sprintf(szMsg,"FAILED to download the tileset: [%s] using CURL version [%s] [%s]",itemName.c_str(),curlVersion->version,result.second.c_str()); +// } + console.addLine(szMsg,true); + } + } + else if(type == ftp_cct_Techtree) { + 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(true); + + selectedTechName = ""; + buttonInstallTech.setEnabled(true); + + if(result.first == ftp_crt_SUCCESS) { + refreshTechs(); + + char szMsg[1024]=""; +// if(lang.hasString("DataMissingTechtreeSuccessDownload") == true) { +// sprintf(szMsg,lang.get("DataMissingTechtreeSuccessDownload").c_str(),getHumanPlayerName().c_str(),gameSettings->getTech().c_str()); +// } +// else { + sprintf(szMsg,"SUCCESSFULLY downloaded the techtree: %s",itemName.c_str()); +// } + console.addLine(szMsg,true); + + // START + // Clear the CRC Cache if it is populated + // + // Clear the CRC file Cache + safeMutexFTPProgress.Lock(); + Checksum::clearFileCache(); + + vector paths = Config::getInstance().getPathListForType(ptTechs); + string pathSearchString = string("/") + itemName + string("/*"); + const string filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, filterFileExt); + + // Refresh CRC + Config &config = Config::getInstance(); + uint32 CRCTechtreeValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), string("/") + itemName + string("/*"), ".xml", NULL); + + safeMutexFTPProgress.ReleaseLock(); + // END + + // Reload tilesets for the UI + //findDirs(Config::getInstance().getPathListForType(ptTechs), techTreeFiles); + } + else { + curl_version_info_data *curlVersion= curl_version_info(CURLVERSION_NOW); + + char szMsg[1024]=""; +// if(lang.hasString("DataMissingTechtreeFailDownload") == true) { +// sprintf(szMsg,lang.get("DataMissingTechtreeFailDownload").c_str(),getHumanPlayerName().c_str(),gameSettings->getTech().c_str(),curlVersion->version); +// } +// else { + sprintf(szMsg,"FAILED to download the techtree: [%s] using CURL version [%s] [%s]",itemName.c_str(),curlVersion->version,result.second.c_str()); +// } + console.addLine(szMsg,true); + } + } +} + +}}//end namespace diff --git a/source/glest_game/menu/menu_state_mods.h b/source/glest_game/menu/menu_state_mods.h new file mode 100644 index 000000000..9e3e89b26 --- /dev/null +++ b/source/glest_game/menu/menu_state_mods.h @@ -0,0 +1,133 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2011 Mark Vejvoda +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#ifndef MENU_STATE_MODS_H_ +#define MENU_STATE_MODS_H_ + +#include "main_menu.h" +#include "map_preview.h" +#include "miniftpclient.h" +#include +#include +#include "miniftpclient.h" +#include "leak_dumper.h" + +namespace Glest { namespace Game { + +enum FTPMessageType { + ftpmsg_None, + ftpmsg_GetMap, + ftpmsg_GetTileset, + ftpmsg_GetTechtree, + ftpmsg_Quit +}; + +typedef vector UserButtons; +typedef vector GraphicLabels; + +// =============================== +// class MenuStateMods +// =============================== + +class MenuStateMods: public MenuState, public FTPClientCallbackInterface { +private: + + GraphicButton buttonReturn; + + GraphicMessageBox mainMessageBox; + FTPMessageType mainMessageBoxState; + + GraphicButton buttonInstallTech; + GraphicButton buttonRemoveTech; + GraphicLabel keyTechScrollBarTitle1; + GraphicLabel keyTechScrollBarTitle2; + GraphicScrollBar keyTechScrollBar; + UserButtons keyTechButtons; + GraphicLabels labelsTech; + + GraphicButton buttonInstallTileset; + GraphicButton buttonRemoveTileset; + GraphicLabel keyTilesetScrollBarTitle1; + GraphicScrollBar keyTilesetScrollBar; + UserButtons keyTilesetButtons; + + GraphicButton buttonInstallMap; + GraphicButton buttonRemoveMap; + GraphicLabel keyMapScrollBarTitle1; + GraphicLabel keyMapScrollBarTitle2; + GraphicScrollBar keyMapScrollBar; + UserButtons keyMapButtons; + GraphicLabels labelsMap; + + int keyButtonsToRender; + int keyButtonsYBase; + int keyButtonsXBase; + int keyButtonsLineHeight; + int keyButtonsHeight; + int keyButtonsWidth; + + Console console; + bool showFullConsole; + + string selectedTechName; + std::vector techListRemote; + std::map techCacheList; + + string selectedTilesetName; + std::vector tilesetListRemote; + std::map tilesetCacheList; + + string selectedMapName; + std::vector mapListRemote; + std::map mapCacheList; + + vector mapFiles; + vector techTreeFiles; + vector tilesetFiles; + vector factionFiles; + + FTPClientThread *ftpClientThread; + std::map > fileFTPProgressList; + + void getTechsLocalList(); + void refreshTechs(); + + void getTilesetsLocalList(); + void refreshTilesets(); + + void getMapsLocalList(); + void refreshMaps(); + +public: + + MenuStateMods(Program *program, MainMenu *mainMenu); + ~MenuStateMods(); + + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState *mouseState); + void render(); + void update(); + + virtual void keyDown(char key); + virtual void keyPress(char c); + virtual void keyUp(char key); + +private: + + void showMessageBox(const string &text, const string &header, bool toggle); + void clearUserButtons(); + virtual void FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, pair result,void *userdata); +}; + +}}//end namespace + +#endif /* MENU_STATE_MODS_H_ */ diff --git a/source/glest_game/menu/menu_state_root.cpp b/source/glest_game/menu/menu_state_root.cpp index ed0a961ce..4a91b63d5 100644 --- a/source/glest_game/menu/menu_state_root.cpp +++ b/source/glest_game/menu/menu_state_root.cpp @@ -20,6 +20,7 @@ #include "menu_state_options.h" #include "menu_state_about.h" #include "menu_state_masterserver.h" +#include "menu_state_mods.h" #include "metrics.h" #include "network_manager.h" #include "network_message.h" @@ -62,6 +63,11 @@ MenuStateRoot::MenuStateRoot(Program *program, MainMenu *mainMenu): buttonMasterserverGame.registerGraphicComponent(containerName,"buttonMasterserverGame"); buttonMasterserverGame.init(425, yPos, 150); yPos-=40; + + buttonMods.registerGraphicComponent(containerName,"buttonMods"); + buttonMods.init(425, yPos, 150); + yPos-=40; + buttonOptions.registerGraphicComponent(containerName,"buttonOptions"); buttonOptions.init(425, yPos, 150); yPos-=40; @@ -74,6 +80,7 @@ MenuStateRoot::MenuStateRoot(Program *program, MainMenu *mainMenu): buttonNewGame.setText(lang.get("NewGame")); buttonJoinGame.setText(lang.get("JoinGame")); buttonMasterserverGame.setText(lang.get("JoinInternetGame")); + buttonMods.setText(lang.get("Mods")); buttonOptions.setText(lang.get("Options")); buttonAbout.setText(lang.get("About")); buttonExit.setText(lang.get("Exit")); @@ -102,6 +109,10 @@ void MenuStateRoot::mouseClick(int x, int y, MouseButton mouseButton){ else if(buttonMasterserverGame.mouseClick(x, y)){ soundRenderer.playFx(coreData.getClickSoundB()); mainMenu->setState(new MenuStateMasterserver(program, mainMenu)); + } + else if(buttonMods.mouseClick(x, y)){ + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateMods(program, mainMenu)); } else if(buttonOptions.mouseClick(x, y)){ soundRenderer.playFx(coreData.getClickSoundB()); @@ -137,6 +148,7 @@ void MenuStateRoot::mouseMove(int x, int y, const MouseState *ms){ buttonNewGame.mouseMove(x, y); buttonJoinGame.mouseMove(x, y); buttonMasterserverGame.mouseMove(x, y); + buttonMods.mouseMove(x, y); buttonOptions.mouseMove(x, y); buttonAbout.mouseMove(x, y); buttonExit.mouseMove(x,y); @@ -180,6 +192,7 @@ void MenuStateRoot::render() { renderer.renderButton(&buttonNewGame); renderer.renderButton(&buttonJoinGame); renderer.renderButton(&buttonMasterserverGame); + renderer.renderButton(&buttonMods); renderer.renderButton(&buttonOptions); renderer.renderButton(&buttonAbout); renderer.renderButton(&buttonExit); diff --git a/source/glest_game/menu/menu_state_root.h b/source/glest_game/menu/menu_state_root.h index e322d0bba..ec7404a90 100644 --- a/source/glest_game/menu/menu_state_root.h +++ b/source/glest_game/menu/menu_state_root.h @@ -28,6 +28,7 @@ private: GraphicButton buttonNewGame; GraphicButton buttonJoinGame; GraphicButton buttonMasterserverGame; + GraphicButton buttonMods; GraphicButton buttonOptions; GraphicButton buttonAbout; GraphicButton buttonExit; diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 6f8f28663..9ed15ee92 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -1259,9 +1259,10 @@ void World::initUnits() { unit->born(); } else { + string unitName = unit->getType()->getName(); delete unit; unit = NULL; - throw runtime_error("Unit cant be placed, this error is caused because there is no enough place to put the units near its start location, make a better map: "+unit->getType()->getName() + " Faction: "+intToStr(i)); + throw runtime_error("Unit: " + unitName + " can't be placed, this error is caused because there\nis not enough room to put all units near their start location.\nmake a better/larger map. Faction: #" + intToStr(i) + " name: " + ft->getName()); } if (unit->getType()->hasSkillClass(scBeBuilt)) { map.flatternTerrain(unit); diff --git a/source/masterserver/createDB.sql b/source/masterserver/createDB.sql index 74cb131ae..b163a83bb 100755 --- a/source/masterserver/createDB.sql +++ b/source/masterserver/createDB.sql @@ -27,3 +27,39 @@ CREATE TABLE IF NOT EXISTS `glestserver` ( INSERT INTO `glestserver` (`lasttime`, `glestVersion`, `platform`, `binaryCompileDate`, `serverTitle`, `ip`, `tech`, `map`, `tileset`, `activeSlots`, `networkSlots`, `connectedClients` ,`externalServerPort`, `country`) VALUES ('2010-05-12 01:41:43', '', '', '', '', '', '', '', '', 0, 0, 0, 0, 'DE'); + + +CREATE TABLE IF NOT EXISTS `glestmaps` ( + `updatetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `glestversion` varchar(30) COLLATE utf8_unicode_ci NOT NULL, + `mapname` varchar(100) COLLATE utf8_unicode_ci NOT NULL, + `playercount` int(11) NOT NULL, + `crc` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, + `description` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, + `url` varchar(1024) COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`mapname`), + KEY `mapname` (`mapname`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci + +CREATE TABLE IF NOT EXISTS `glesttilesets` ( + `updatetime` timestamp NOT NULL default CURRENT_TIMESTAMP, + `glestversion` varchar(30) collate utf8_unicode_ci NOT NULL, + `tilesetname` varchar(100) collate utf8_unicode_ci NOT NULL, + `crc` varchar(100) collate utf8_unicode_ci, + `description` varchar(255) collate utf8_unicode_ci, + `url` varchar(1024) collate utf8_unicode_ci NOT NULL, + PRIMARY KEY (`tilesetname`), + KEY `tilesetname` (`tilesetname`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +CREATE TABLE IF NOT EXISTS `glesttechs` ( + `updatetime` timestamp NOT NULL default CURRENT_TIMESTAMP, + `glestversion` varchar(30) collate utf8_unicode_ci NOT NULL, + `techname` varchar(100) collate utf8_unicode_ci NOT NULL, + `factioncount` int(11) NOT NULL, + `crc` varchar(100) collate utf8_unicode_ci, + `description` varchar(255) collate utf8_unicode_ci, + `url` varchar(1024) collate utf8_unicode_ci NOT NULL, + PRIMARY KEY (`techname`), + KEY `techname` (`techname`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/source/masterserver/showMapsForGlest.php b/source/masterserver/showMapsForGlest.php new file mode 100644 index 000000000..3dc636371 --- /dev/null +++ b/source/masterserver/showMapsForGlest.php @@ -0,0 +1,33 @@ + + diff --git a/source/masterserver/showTechsForGlest.php b/source/masterserver/showTechsForGlest.php new file mode 100644 index 000000000..eaa375caf --- /dev/null +++ b/source/masterserver/showTechsForGlest.php @@ -0,0 +1,33 @@ + + diff --git a/source/masterserver/showTilesetsForGlest.php b/source/masterserver/showTilesetsForGlest.php new file mode 100644 index 000000000..98d5e88ea --- /dev/null +++ b/source/masterserver/showTilesetsForGlest.php @@ -0,0 +1,33 @@ + + diff --git a/source/shared_lib/include/platform/posix/miniftpclient.h b/source/shared_lib/include/platform/posix/miniftpclient.h index c4d8d77c1..866c478d0 100644 --- a/source/shared_lib/include/platform/posix/miniftpclient.h +++ b/source/shared_lib/include/platform/posix/miniftpclient.h @@ -51,7 +51,8 @@ public: string currentFilename; }; - virtual void FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result, void *userdata) = 0; + virtual void FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, pair result, void *userdata) = 0; }; class FTPClientThread : public BaseThread @@ -65,22 +66,22 @@ protected: std::pair techtreesPath; Mutex mutexMapFileList; - vector mapFileList; + vector > mapFileList; Mutex mutexTilesetList; - vector tilesetList; + vector > tilesetList; Mutex mutexTechtreeList; - vector techtreeList; + vector > techtreeList; - void getMapFromServer(string mapFilename); - FTP_Client_ResultType getMapFromServer(string mapFileName, string ftpUser, string ftpUserPassword); + void getMapFromServer(pair mapFilename); + pair getMapFromServer(pair mapFileName, string ftpUser, string ftpUserPassword); - void getTilesetFromServer(string tileSetName); - FTP_Client_ResultType getTilesetFromServer(string tileSetName, string tileSetNameSubfolder, string ftpUser, string ftpUserPassword, bool findArchive); + void getTilesetFromServer(pair tileSetName); + pair getTilesetFromServer(pair tileSetName, string tileSetNameSubfolder, string ftpUser, string ftpUserPassword, bool findArchive); - void getTechtreeFromServer(string techtreeName); - FTP_Client_ResultType getTechtreeFromServer(string techtreeName, string ftpUser, string ftpUserPassword); + void getTechtreeFromServer(pair techtreeName); + pair getTechtreeFromServer(pair techtreeName, string ftpUser, string ftpUserPassword); Mutex mutexProgressMutex; @@ -88,7 +89,7 @@ protected: string fileArchiveExtractCommand; string fileArchiveExtractCommandParameters; - FTP_Client_ResultType getFileFromServer(string fileNameTitle, + pair getFileFromServer(pair fileNameTitle, string remotePath, string destFileSaveAs, string ftpUser, string ftpUserPassword, vector *wantDirListOnly=NULL); @@ -106,9 +107,9 @@ public: virtual void signalQuit(); virtual bool shutdownAndWait(); - void addMapToRequests(string mapFilename); - void addTilesetToRequests(string tileSetName); - void addTechtreeToRequests(string techtreeName); + void addMapToRequests(string mapFilename,string URL=""); + void addTilesetToRequests(string tileSetName,string URL=""); + void addTechtreeToRequests(string techtreeName,string URL=""); FTPClientCallbackInterface * getCallBackObject(); void setCallBackObject(FTPClientCallbackInterface *value); diff --git a/source/shared_lib/sources/platform/common/platform_common.cpp b/source/shared_lib/sources/platform/common/platform_common.cpp index c9dd4a48c..0d86a8390 100644 --- a/source/shared_lib/sources/platform/common/platform_common.cpp +++ b/source/shared_lib/sources/platform/common/platform_common.cpp @@ -194,6 +194,8 @@ int64 Chrono::getCurTicks() { // ===================================== void Tokenize(const string& str,vector& tokens,const string& delimiters) { + +/* // Skip delimiters at beginning. string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first "non-delimiter". @@ -207,6 +209,22 @@ void Tokenize(const string& str,vector& tokens,const string& delimiters) // Find next "non-delimiter" pos = str.find_first_of(delimiters, lastPos); } +*/ + + // Assume textLine contains the line of text to parse. + string textLine = str; + + size_t pos = 0; + while( true ) { + size_t nextPos = textLine.find( delimiters, pos ); + if( nextPos == textLine.npos ) { + tokens.push_back(textLine.substr(pos, textLine.length( ))); + break; + } + tokens.push_back( string( textLine.substr( pos, nextPos - pos ) ) ); + pos = nextPos + 1; + } + } void findDirs(string path, vector &results, bool errorOnNotFound,bool keepDuplicates) { @@ -372,7 +390,9 @@ bool isdir(const char *path) void removeFolder(const string path) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); - string deletePath = path + "*"; + string deletePath = path; + endPathWithSlash(deletePath); + deletePath += "{,.}*"; vector results = getFolderTreeContentsListRecursively(deletePath, "", true); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] results.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),results.size()); @@ -381,6 +401,11 @@ void removeFolder(const string path) { for(int i = results.size() -1; i >= 0; --i) { string item = results[i]; + + if(item.find(".svn") != string::npos) { + printf("!!!!!!!!!!!!!!!!!! FOUND SPECIAL FOLDER [%s] in [%s]\n",item.c_str(),path.c_str()); + } + if(isdir(item.c_str()) == false) { //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] file item [%s]\n",__FILE__,__FUNCTION__,__LINE__,item.c_str()); @@ -395,6 +420,9 @@ void removeFolder(const string path) { string item = results[i]; SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] item [%s] isdir(item.c_str()) = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(), isdir(item.c_str())); if(isdir(item.c_str()) == true) { + + printf("~~~~~ REMOVE FOLDER [%s] in [%s]\n",item.c_str(),path.c_str()); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] item [%s]\n",__FILE__,__FUNCTION__,__LINE__,item.c_str()); #ifdef WIN32 int result = _rmdir(item.c_str()); @@ -402,6 +430,11 @@ void removeFolder(const string path) { int result = rmdir(item.c_str()); #endif SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] item [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(),result); + + if(result != 0 && item != path) { + printf("CANNOT REMOVE FOLDER [%s] in [%s]\n",item.c_str(),path.c_str()); + removeFolder(item); + } } } @@ -861,7 +894,12 @@ vector getFolderTreeContentsListRecursively(const string &path, const st glob_t globbuf; - int res = glob(mypath.c_str(), 0, 0, &globbuf); + int globFlags = 0; + if(EndsWith(mypath,"{,.}*") == true) { + globFlags = GLOB_BRACE; + } + + int res = glob(mypath.c_str(), globFlags, 0, &globbuf); #if !defined(__APPLE__) && !defined(__FreeBSD__) if(res < 0) { std::stringstream msg; @@ -872,25 +910,25 @@ vector getFolderTreeContentsListRecursively(const string &path, const st for(int i = 0; i < globbuf.gl_pathc; ++i) { const char* p = globbuf.gl_pathv[i]; - if(isdir(p) == false) { - bool addFile = true; - //if(EndsWith(p, ".") == true || EndsWith(p, "..") == true || EndsWith(p, ".svn") == true) { - // addFile = false; - //} - //else - if(filterFileExt != "") { - addFile = EndsWith(p, filterFileExt); - } + bool skipItem = (EndsWith(p, ".") == true || EndsWith(p, "..") == true); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("~~~~~~~~~~~ Glob file [%s] skipItem = %d\n",p,skipItem); - if(addFile) { - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p); - resultFiles.push_back(p); - } - } - else if(includeFolders == true) { - resultFiles.push_back(p); - } + if(skipItem == false) { + if(isdir(p) == false) { + bool addFile = true; + if(filterFileExt != "") { + addFile = EndsWith(p, filterFileExt); + } + if(addFile) { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p); + resultFiles.push_back(p); + } + } + else if(includeFolders == true) { + resultFiles.push_back(p); + } + } } globfree(&globbuf); @@ -899,7 +937,8 @@ vector getFolderTreeContentsListRecursively(const string &path, const st #if defined(__APPLE__) || defined(__FreeBSD__) res = glob(mypath.c_str(), 0, 0, &globbuf); #else //APPLE doesn't have the GLOB_ONLYDIR definition.. - res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf); + globFlags |= GLOB_ONLYDIR; + res = glob(mypath.c_str(), globFlags, 0, &globbuf); #endif #if !defined(__APPLE__) && !defined(__FreeBSD__) @@ -919,14 +958,26 @@ vector getFolderTreeContentsListRecursively(const string &path, const st continue; #endif const char* p = globbuf.gl_pathv[i]; - if(includeFolders == true) { - resultFiles.push_back(p); + + bool skipItem = (EndsWith(p, ".") == true || EndsWith(p, "..") == true); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("~~~~~~~~~~~ Glob folder [%s] skipItem = %d\n",p,skipItem); + + if(skipItem == false) { + if(includeFolders == true) { + resultFiles.push_back(p); + } + + string currentPath = p; + endPathWithSlash(currentPath); + + if(EndsWith(mypath,"{,.}*") == true) { + currentPath += "{,.}*"; + } + else { + currentPath += "*"; + } + resultFiles = getFolderTreeContentsListRecursively(currentPath, filterFileExt, includeFolders,&resultFiles); } - - string currentPath = p; - endPathWithSlash(currentPath); - - resultFiles = getFolderTreeContentsListRecursively(currentPath + "*", filterFileExt, includeFolders,&resultFiles); } globfree(&globbuf); diff --git a/source/shared_lib/sources/platform/posix/miniftpclient.cpp b/source/shared_lib/sources/platform/posix/miniftpclient.cpp index 941a68b64..4a8344dbe 100644 --- a/source/shared_lib/sources/platform/posix/miniftpclient.cpp +++ b/source/shared_lib/sources/platform/posix/miniftpclient.cpp @@ -193,7 +193,7 @@ int file_progress(struct FtpFile *out,double download_total, double download_now stats.currentFilename = out->currentFilename; MutexSafeWrapper safeMutex(out->ftpServer->getProgressMutex(),string(__FILE__) + "_" + intToStr(__LINE__)); - out->ftpServer->getCallBackObject()->FTPClient_CallbackEvent(out->itemName, ftp_cct_DownloadProgress, ftp_crt_SUCCESS, &stats); + out->ftpServer->getCallBackObject()->FTPClient_CallbackEvent(out->itemName, ftp_cct_DownloadProgress, make_pair(ftp_crt_SUCCESS,""), &stats); } return 0; @@ -236,18 +236,20 @@ bool FTPClientThread::shutdownAndWait() { } -FTP_Client_ResultType FTPClientThread::getMapFromServer(string mapFileName, string ftpUser, string ftpUserPassword) { - FTP_Client_ResultType result = ftp_crt_FAIL; +pair FTPClientThread::getMapFromServer(pair mapFileName, string ftpUser, string ftpUserPassword) { + pair result = make_pair(ftp_crt_FAIL,""); string destFileExt = ""; string destFile = this->mapsPath.second; endPathWithSlash(destFile); - destFile += mapFileName; + destFile += mapFileName.first; - if(EndsWith(destFile,".mgm") == false && EndsWith(destFile,".gbm") == false) { - destFileExt = ".mgm"; - destFile += destFileExt; + if(mapFileName.second == "") { + if(EndsWith(destFile,".mgm") == false && EndsWith(destFile,".gbm") == false) { + destFileExt = ".mgm"; + destFile += destFileExt; + } } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread about to try to RETR into [%s]\n",destFile.c_str()); @@ -270,7 +272,13 @@ FTP_Client_ResultType FTPClientThread::getMapFromServer(string mapFileName, stri ftpfile.stream = NULL; char szBuf[1024]=""; - sprintf(szBuf,"ftp://%s:%s@%s:%d/%s%s",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,mapFileName.c_str(),destFileExt.c_str()); + if(mapFileName.second != "") { + sprintf(szBuf,"%s",mapFileName.second.c_str()); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + } + else { + sprintf(szBuf,"ftp://%s:%s@%s:%d/%s%s",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,mapFileName.first.c_str(),destFileExt.c_str()); + } curl_easy_setopt(curl, CURLOPT_URL,szBuf); curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); @@ -280,6 +288,7 @@ FTP_Client_ResultType FTPClientThread::getMapFromServer(string mapFileName, stri /* Set a pointer to our struct to pass to the callback */ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); + // Max 10 minutes to transfer curl_easy_setopt(curl, CURLOPT_TIMEOUT, 600); @@ -288,16 +297,17 @@ FTP_Client_ResultType FTPClientThread::getMapFromServer(string mapFileName, stri CURLcode res = curl_easy_perform(curl); if(res != CURLE_OK) { + result.second = curl_easy_strerror(res); // we failed printf("curl FAILED with: %d [%s] szBuf [%s]\n", res,curl_easy_strerror(res),szBuf); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"curl FAILED with: %d [%s] szBuf [%s]\n", res,curl_easy_strerror(res),szBuf); if(res == CURLE_PARTIAL_FILE) { - result = ftp_crt_PARTIALFAIL; + result.first = ftp_crt_PARTIALFAIL; } } else { - result = ftp_crt_SUCCESS; + result.first = ftp_crt_SUCCESS; } SystemFlags::cleanupHTTP(&curl); @@ -307,76 +317,100 @@ FTP_Client_ResultType FTPClientThread::getMapFromServer(string mapFileName, stri fclose(ftpfile.stream); ftpfile.stream = NULL; } - if(result != ftp_crt_SUCCESS) { + if(result.first != ftp_crt_SUCCESS) { removeFile(destFile); } return result; } -void FTPClientThread::getMapFromServer(string mapFileName) { - FTP_Client_ResultType result = getMapFromServer(mapFileName + ".mgm", FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); - if(result == ftp_crt_FAIL && this->getQuitStatus() == false) { - result = getMapFromServer(mapFileName + ".gbm", FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); - if(result == ftp_crt_FAIL && this->getQuitStatus() == false) { - result = getMapFromServer(mapFileName + ".mgm", FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD); - if(result == ftp_crt_FAIL && this->getQuitStatus() == false) { - result = getMapFromServer(mapFileName + ".gbm", FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD); - } - } - } +void FTPClientThread::getMapFromServer(pair mapFileName) { + pair result = make_pair(ftp_crt_FAIL,""); + if(mapFileName.second != "") { + result = getMapFromServer(mapFileName, "", ""); + } + else { + pair findMapFileName = mapFileName; + findMapFileName.first += + ".mgm"; + + result = getMapFromServer(findMapFileName, FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); + if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + findMapFileName = mapFileName; + findMapFileName.first += + ".gbm"; + result = getMapFromServer(findMapFileName, FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); + if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + findMapFileName = mapFileName; + findMapFileName.first += + ".mgm"; + result = getMapFromServer(findMapFileName, FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD); + if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + findMapFileName = mapFileName; + findMapFileName.first += + ".gbm"; + result = getMapFromServer(findMapFileName, FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD); + } + } + } + } MutexSafeWrapper safeMutex(this->getProgressMutex(),string(__FILE__) + "_" + intToStr(__LINE__)); if(this->pCBObject != NULL) { - this->pCBObject->FTPClient_CallbackEvent(mapFileName,ftp_cct_Map,result,NULL); + this->pCBObject->FTPClient_CallbackEvent(mapFileName.first,ftp_cct_Map,result,NULL); } } -void FTPClientThread::addMapToRequests(string mapFilename) { +void FTPClientThread::addMapToRequests(string mapFilename,string URL) { + std::pair item = make_pair(mapFilename,URL); MutexSafeWrapper safeMutex(&mutexMapFileList,string(__FILE__) + "_" + intToStr(__LINE__)); - if(std::find(mapFileList.begin(),mapFileList.end(),mapFilename) == mapFileList.end()) { - mapFileList.push_back(mapFilename); + if(std::find(mapFileList.begin(),mapFileList.end(),item) == mapFileList.end()) { + mapFileList.push_back(item); } } -void FTPClientThread::addTilesetToRequests(string tileSetName) { +void FTPClientThread::addTilesetToRequests(string tileSetName,string URL) { + std::pair item = make_pair(tileSetName,URL); MutexSafeWrapper safeMutex(&mutexTilesetList,string(__FILE__) + "_" + intToStr(__LINE__)); - if(std::find(tilesetList.begin(),tilesetList.end(),tileSetName) == tilesetList.end()) { - tilesetList.push_back(tileSetName); + if(std::find(tilesetList.begin(),tilesetList.end(),item) == tilesetList.end()) { + tilesetList.push_back(item); } } -void FTPClientThread::addTechtreeToRequests(string techtreeName) { +void FTPClientThread::addTechtreeToRequests(string techtreeName,string URL) { + std::pair item = make_pair(techtreeName,URL); MutexSafeWrapper safeMutex(&mutexTechtreeList,string(__FILE__) + "_" + intToStr(__LINE__)); - if(std::find(techtreeList.begin(),techtreeList.end(),techtreeName) == techtreeList.end()) { - techtreeList.push_back(techtreeName); + if(std::find(techtreeList.begin(),techtreeList.end(),item) == techtreeList.end()) { + techtreeList.push_back(item); } } -void FTPClientThread::getTilesetFromServer(string tileSetName) { +void FTPClientThread::getTilesetFromServer(pair tileSetName) { 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) { - if(findArchive == true) { - result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, false); - } - if(result == ftp_crt_FAIL && this->getQuitStatus() == false) { - result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, findArchive); + pair result = make_pair(ftp_crt_FAIL,""); + if(tileSetName.second != "") { + result = getTilesetFromServer(tileSetName, "", "", "", findArchive); + } + else { + result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, findArchive); + if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + if(findArchive == true) { + result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, false); + } + if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, findArchive); - if(findArchive == true) { - result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, false); - } - } - } + if(findArchive == true) { + result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, false); + } + } + } + } MutexSafeWrapper safeMutex(this->getProgressMutex(),string(__FILE__) + "_" + intToStr(__LINE__)); if(this->pCBObject != NULL) { - this->pCBObject->FTPClient_CallbackEvent(tileSetName,ftp_cct_Tileset,result,NULL); + this->pCBObject->FTPClient_CallbackEvent(tileSetName.first,ftp_cct_Tileset,result,NULL); } } -FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, +pair FTPClientThread::getTilesetFromServer(pair tileSetName, string tileSetNameSubfolder, string ftpUser, string ftpUserPassword, bool findArchive) { @@ -550,18 +584,23 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, if(findArchive == true) { destFileSaveAs = this->tilesetsPath.second; endPathWithSlash(destFileSaveAs); - destFileSaveAs += tileSetName + this->fileArchiveExtension; + destFileSaveAs += tileSetName.first + this->fileArchiveExtension; - remotePath = tileSetName + this->fileArchiveExtension; + if(tileSetName.second != "") { + remotePath = tileSetName.second; + } + else { + remotePath = tileSetName.first + this->fileArchiveExtension; + } //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 { getFolderContents = true; - remotePath = tileSetName + "/"; + remotePath = tileSetName.first + "/"; destFileSaveAs = this->tilesetsPath.second; endPathWithSlash(destFileSaveAs); - destFileSaveAs += tileSetName; + destFileSaveAs += tileSetName.first; destFileSaveAsNewFile = destFileSaveAs; endPathWithSlash(destFileSaveAsNewFile); destFileSaveAs += ".tmp"; @@ -571,10 +610,10 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, } else { getFolderContents = true; - remotePath = tileSetName + "/" + tileSetNameSubfolder + "/"; + remotePath = tileSetName.first + "/" + tileSetNameSubfolder + "/"; destFileSaveAs = this->tilesetsPath.second; endPathWithSlash(destFileSaveAs); - destFileSaveAs += tileSetName; + destFileSaveAs += tileSetName.first; endPathWithSlash(destFileSaveAs); destFileSaveAs += tileSetNameSubfolder; @@ -591,23 +630,24 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, pWantDirListOnly = &wantDirListOnly; } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("FTPClientThread::getTilesetFromServer [%s] remotePath [%s] destFileSaveAs [%s] getFolderContents = %d\n",tileSetName.c_str(),remotePath.c_str(),destFileSaveAs.c_str(),getFolderContents); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("FTPClientThread::getTilesetFromServer [%s] remotePath [%s] destFileSaveAs [%s] getFolderContents = %d\n",tileSetName.first.c_str(),remotePath.c_str(),destFileSaveAs.c_str(),getFolderContents); - FTP_Client_ResultType result = getFileFromServer(tileSetName, + pair result = getFileFromServer(tileSetName, remotePath, destFileSaveAs,ftpUser, ftpUserPassword, pWantDirListOnly); // Extract the archive - if(result == ftp_crt_SUCCESS) { + if(result.first == ftp_crt_SUCCESS) { if(findArchive == true) { string destRootArchiveFolder = this->tilesetsPath.second; endPathWithSlash(destRootArchiveFolder); string extractCmd = getFullFileArchiveExtractCommand(this->fileArchiveExtractCommand, this->fileArchiveExtractCommandParameters, destRootArchiveFolder, - destRootArchiveFolder + tileSetName + this->fileArchiveExtension); + destRootArchiveFolder + tileSetName.first + this->fileArchiveExtension); if(executeShellCommand(extractCmd) == false) { - result = ftp_crt_FAIL; + result.first = ftp_crt_FAIL; + result.second = "failed to extract arhcive!"; } return result; @@ -627,7 +667,7 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, remotePath + fileFromList, destFileSaveAsNewFile + fileFromList, ftpUser, ftpUserPassword); - if(result != ftp_crt_SUCCESS) { + if(result.first != ftp_crt_SUCCESS) { break; } } @@ -635,7 +675,7 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, result = getTilesetFromServer(tileSetName, fileFromList, ftpUser, ftpUserPassword, findArchive); - if(result != ftp_crt_SUCCESS) { + if(result.first != ftp_crt_SUCCESS) { break; } } @@ -644,10 +684,10 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, } } - if(result != ftp_crt_SUCCESS && findArchive == false) { + if(result.first != ftp_crt_SUCCESS && findArchive == false) { string destRootFolder = this->tilesetsPath.second; endPathWithSlash(destRootFolder); - destRootFolder += tileSetName; + destRootFolder += tileSetName.first; endPathWithSlash(destRootFolder); removeFolder(destRootFolder); @@ -656,23 +696,28 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, return result; } -void FTPClientThread::getTechtreeFromServer(string techtreeName) { - FTP_Client_ResultType result = ftp_crt_FAIL; +void FTPClientThread::getTechtreeFromServer(pair techtreeName) { + pair result = make_pair(ftp_crt_FAIL,""); bool findArchive = executeShellCommand(this->fileArchiveExtractCommand); if(findArchive == true) { - result = getTechtreeFromServer(techtreeName, FTP_TECHTREES_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); - if(result == ftp_crt_FAIL && this->getQuitStatus() == false) { - result = getTechtreeFromServer(techtreeName, FTP_TECHTREES_USERNAME, FTP_COMMON_PASSWORD); + if(techtreeName.second != "") { + result = getTechtreeFromServer(techtreeName, "", ""); + } + else { + result = getTechtreeFromServer(techtreeName, FTP_TECHTREES_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); + if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + result = getTechtreeFromServer(techtreeName, FTP_TECHTREES_USERNAME, FTP_COMMON_PASSWORD); + } } } MutexSafeWrapper safeMutex(this->getProgressMutex(),string(__FILE__) + "_" + intToStr(__LINE__)); if(this->pCBObject != NULL) { - this->pCBObject->FTPClient_CallbackEvent(techtreeName,ftp_cct_Techtree,result,NULL); + this->pCBObject->FTPClient_CallbackEvent(techtreeName.first,ftp_cct_Techtree,result,NULL); } } -FTP_Client_ResultType FTPClientThread::getTechtreeFromServer(string techtreeName, +pair FTPClientThread::getTechtreeFromServer(pair techtreeName, string ftpUser, string ftpUserPassword) { /* @@ -805,27 +850,32 @@ FTP_Client_ResultType FTPClientThread::getTechtreeFromServer(string techtreeName string destRootFolder = this->techtreesPath.second; endPathWithSlash(destRootFolder); string destRootArchiveFolder = destRootFolder; - destRootFolder += techtreeName; + destRootFolder += techtreeName.first; endPathWithSlash(destRootFolder); string destFile = this->techtreesPath.second; endPathWithSlash(destFile); - destFile += techtreeName; + destFile += techtreeName.first; string destFileSaveAs = destFile + this->fileArchiveExtension; endPathWithSlash(destFile); - string remotePath = techtreeName + this->fileArchiveExtension; - FTP_Client_ResultType result = getFileFromServer(techtreeName, + string remotePath = techtreeName.first + this->fileArchiveExtension; + if(techtreeName.second != "") { + remotePath = techtreeName.second; + } + + pair result = getFileFromServer(techtreeName, remotePath, destFileSaveAs, ftpUser, ftpUserPassword); // Extract the archive - if(result == ftp_crt_SUCCESS) { + if(result.first == ftp_crt_SUCCESS) { string extractCmd = getFullFileArchiveExtractCommand(this->fileArchiveExtractCommand, this->fileArchiveExtractCommandParameters, destRootArchiveFolder, - destRootArchiveFolder + techtreeName + this->fileArchiveExtension); + destRootArchiveFolder + techtreeName.first + this->fileArchiveExtension); if(executeShellCommand(extractCmd) == false) { - result = ftp_crt_FAIL; + result.first = ftp_crt_FAIL; + result.second = "failed to extract archive!"; } } @@ -834,10 +884,10 @@ FTP_Client_ResultType FTPClientThread::getTechtreeFromServer(string techtreeName } -FTP_Client_ResultType FTPClientThread::getFileFromServer(string fileNameTitle, +pair FTPClientThread::getFileFromServer(pair fileNameTitle, string remotePath, string destFileSaveAs, string ftpUser, string ftpUserPassword, vector *wantDirListOnly) { - FTP_Client_ResultType result = ftp_crt_FAIL; + pair result = make_pair(ftp_crt_FAIL,""); if(wantDirListOnly) { (*wantDirListOnly).clear(); } @@ -854,7 +904,7 @@ FTP_Client_ResultType FTPClientThread::getFileFromServer(string fileNameTitle, SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread about to try to RETR into [%s] wantDirList = %d\n",destFileSaveAs.c_str(),wantDirList); struct FtpFile ftpfile = { - fileNameTitle.c_str(), + fileNameTitle.first.c_str(), destFileSaveAs.c_str(), // name to store the file as if successful NULL, NULL, @@ -868,7 +918,13 @@ FTP_Client_ResultType FTPClientThread::getFileFromServer(string fileNameTitle, ftpfile.stream = NULL; char szBuf[1024]=""; - sprintf(szBuf,"ftp://%s:%s@%s:%d/%s",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,remotePath.c_str()); + if(fileNameTitle.second != "") { + sprintf(szBuf,"%s",fileNameTitle.second.c_str()); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + } + else { + sprintf(szBuf,"ftp://%s:%s@%s:%d/%s",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,remotePath.c_str()); + } curl_easy_setopt(curl, CURLOPT_URL,szBuf); curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); @@ -905,12 +961,13 @@ FTP_Client_ResultType FTPClientThread::getFileFromServer(string fileNameTitle, CURLcode res = curl_easy_perform(curl); if(res != CURLE_OK) { + result.second = curl_easy_strerror(res); // we failed printf("curl FAILED with: %d [%s] attempting to remove folder contents [%s] szBuf [%s] ftpfile.isValidXfer = %d, pathCreated = %d\n", res,curl_easy_strerror(res),destRootFolder.c_str(),szBuf,ftpfile.isValidXfer,pathCreated); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"curl FAILED with: %d [%s] attempting to remove folder contents [%s] szBuf [%s] ftpfile.isValidXfer = %d, pathCreated = %d\n", res,curl_easy_strerror(res),destRootFolder.c_str(),szBuf,ftpfile.isValidXfer,pathCreated); if(res == CURLE_PARTIAL_FILE || ftpfile.isValidXfer == true) { - result = ftp_crt_PARTIALFAIL; + result.first = ftp_crt_PARTIALFAIL; } if(destRootFolder != "") { @@ -923,7 +980,7 @@ FTP_Client_ResultType FTPClientThread::getFileFromServer(string fileNameTitle, } } else { - result = ftp_crt_SUCCESS; + result.first = ftp_crt_SUCCESS; if(wantDirListOnly) { if(ftpfile.stream) { @@ -987,7 +1044,7 @@ void FTPClientThread::execute() { while(this->getQuitStatus() == false) { MutexSafeWrapper safeMutex(&mutexMapFileList,string(__FILE__) + "_" + intToStr(__LINE__)); if(mapFileList.size() > 0) { - string mapFilename = mapFileList[0]; + pair mapFilename = mapFileList[0]; mapFileList.erase(mapFileList.begin() + 0); safeMutex.ReleaseLock(); @@ -1003,7 +1060,7 @@ void FTPClientThread::execute() { MutexSafeWrapper safeMutex2(&mutexTilesetList,string(__FILE__) + "_" + intToStr(__LINE__)); if(tilesetList.size() > 0) { - string tileset = tilesetList[0]; + pair tileset = tilesetList[0]; tilesetList.erase(tilesetList.begin() + 0); safeMutex2.ReleaseLock(); @@ -1015,7 +1072,7 @@ void FTPClientThread::execute() { MutexSafeWrapper safeMutex3(&mutexTechtreeList,string(__FILE__) + "_" + intToStr(__LINE__)); if(techtreeList.size() > 0) { - string techtree = techtreeList[0]; + pair techtree = techtreeList[0]; techtreeList.erase(techtreeList.begin() + 0); safeMutex3.ReleaseLock();