- bugfix for shared team resources

- added some new internal feature code to test auto updates for a future release
This commit is contained in:
SoftCoder 2014-12-30 12:16:35 -08:00
parent bcd6c7b310
commit efa7cb0346
10 changed files with 628 additions and 131 deletions

View File

@ -31,7 +31,7 @@ const char *mailString = " http://bugs.megaglest.org";
// !! Use minor versions !! Only major and minor version control compatibility!
// typical version numbers look like this: v3.11-beta1.0 v3.12-dev v3.12.0
// don't forget to update mk/linux/mg-version.sh
const string glestVersionString = "v3.11-beta2.0";
const string glestVersionString = "v3.11-dev";
const string lastCompatibleSaveGameVersionString = "v3.9.0";
#if defined(GITVERSION)
@ -53,7 +53,7 @@ string getCrashDumpFileName(){
return "megaglest" + glestVersionString + ".dmp";
}
string getPlatformNameString() {
string getPlatformTypeNameString() {
static string platform;
if(platform == "") {
#if defined(WIN32)
@ -95,27 +95,42 @@ string getPlatformNameString() {
#else
platform = "???";
#endif
}
return platform;
}
string getPlatformArchTypeNameString() {
static string platform;
if(platform == "") {
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_WIN64)
platform += "-X64";
platform = "-X64";
#elif defined(_M_ALPHA) || defined(__alpha__)
platform += "-ALPHA";
platform = "-ALPHA";
#elif defined(_M_IA64) || defined(__ia64__)
platform += "-IA64";
platform = "-IA64";
#elif defined(_M_MRX000) || defined(__mips__)
platform += "-MIPS";
platform = "-MIPS";
#elif defined(_M_PPC) || defined(__powerpc__)
platform += "-POWERPC";
platform = "-POWERPC";
#elif defined(__sparc__)
platform += "-SPARC";
platform = "-SPARC";
#elif defined(_M_ARM_FP) || defined(__arm__) || defined(_M_ARM)
platform += "-ARM";
platform = "-ARM";
#endif
}
return platform;
}
string getPlatformNameString() {
static string platform;
if(platform == "") {
platform = getPlatformTypeNameString() + getPlatformArchTypeNameString();
}
return platform;
}
string getGITRevisionString() {
return GIT_Rev;
}
@ -197,7 +212,7 @@ string getAboutString1(int i) {
case 0: return "MegaGlest " + glestVersionString + " (" + "Shared Library " + sharedLibVersionString + ")";
case 1: return "Built: " + string(__DATE__) + " " + GIT_Rev;
case 2: return "Copyright 2001-2010 The Glest Team";
case 3: return "Copyright 2010-2014 The MegaGlest Team";
case 3: return "Copyright 2010-2015 The MegaGlest Team";
}
return "";
}

View File

@ -34,6 +34,8 @@ extern const string networkVersionString;
void initSpecialStrings();
string getCrashDumpFileName();
string getPlatformTypeNameString();
string getPlatformArchTypeNameString();
string getPlatformNameString();
string getGITRevisionString();
string getRAWGITRevisionString();

View File

@ -25,6 +25,7 @@
#include "network_message.h"
#include "socket.h"
#include "auto_test.h"
#include <stdio.h>
#include "leak_dumper.h"
@ -34,10 +35,16 @@ namespace Glest{ namespace Game{
// class MenuStateRoot
// =====================================================
bool MenuStateRoot::gameUpdateChecked = false;
MenuStateRoot::MenuStateRoot(Program *program, MainMenu *mainMenu):
MenuState(program, mainMenu, "root")
MenuState(program, mainMenu, "root"), updatesHttpServerThread(NULL)
{
containerName = "MainMenu";
ftpClientThread = NULL;
lastDownloadProgress = 0;
Lang &lang= Lang::getInstance();
int yPos=440;
@ -87,6 +94,10 @@ MenuStateRoot::MenuStateRoot(Program *program, MainMenu *mainMenu):
errorMessageBox.init(lang.getString("Ok"));
errorMessageBox.setEnabled(false);
ftpMessageBox.registerGraphicComponent(containerName,"ftpMessageBox");
ftpMessageBox.init(lang.getString("Yes"), lang.getString("No"));
ftpMessageBox.setEnabled(false);
//PopupMenu popupMenu;
std::vector<string> menuItems;
menuItems.push_back("1");
@ -101,6 +112,57 @@ MenuStateRoot::MenuStateRoot(Program *program, MainMenu *mainMenu):
GraphicComponent::applyAllCustomProperties(containerName);
}
MenuStateRoot::~MenuStateRoot() {
if(updatesHttpServerThread != NULL) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
updatesHttpServerThread->setSimpleTaskInterfaceValid(false);
updatesHttpServerThread->signalQuit();
updatesHttpServerThread->setThreadOwnerValid(false);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
if( updatesHttpServerThread->canShutdown(true) == true &&
updatesHttpServerThread->shutdownAndWait() == true) {
delete updatesHttpServerThread;
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
updatesHttpServerThread = NULL;
}
if(ftpClientThread != NULL) {
ftpClientThread->setCallBackObject(NULL);
ftpClientThread->signalQuit();
sleep(0);
if(ftpClientThread->canShutdown(true) == true &&
ftpClientThread->shutdownAndWait() == true) {
delete ftpClientThread;
}
else {
char szBuf[8096]="";
snprintf(szBuf,8096,"In [%s::%s %d] Error cannot shutdown ftpClientThread\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s",szBuf);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf);
//publishToMasterserverThread->cleanup();
}
ftpClientThread = NULL;
// ftpClientThread->signalQuit();
// ftpClientThread->setCallBackObject(NULL);
// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
// if( ftpClientThread->shutdownAndWait() == true) {
// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
// delete ftpClientThread;
// }
// ftpClientThread = NULL;
// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}
void MenuStateRoot::reloadUI() {
Lang &lang= Lang::getInstance();
@ -122,6 +184,8 @@ void MenuStateRoot::reloadUI() {
mainMessageBox.init(lang.getString("Yes"), lang.getString("No"));
errorMessageBox.init(lang.getString("Ok"));
ftpMessageBox.init(lang.getString("Yes"), lang.getString("No"));
console.resetFonts();
GraphicComponent::reloadFontsForRegisterGraphicComponents(containerName);
@ -163,6 +227,28 @@ void MenuStateRoot::mouseClick(int x, int y, MouseButton mouseButton){
errorMessageBox.setEnabled(false);
}
}
else if(ftpMessageBox.getEnabled()) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
int button= 0;
if(ftpMessageBox.mouseClick(x, y, button)) {
ftpMessageBox.setEnabled(false);
if(button == 0) {
startFTPClientIfRequired();
lastDownloadProgress = 0;
printf("Adding ftpFileName [%s] ftpFileURL [%s]\n",ftpFileName.c_str(),ftpFileURL.c_str());
if(ftpClientThread != NULL) ftpClientThread->addTempFileToRequests(ftpFileName,ftpFileURL);
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),mutexOwnerId);
if(ftpClientThread != NULL && ftpClientThread->getProgressMutex() != NULL) ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId);
fileFTPProgressList[ftpFileName] = pair<int,string>(0,"");
safeMutexFTPProgress.ReleaseLock();
}
}
}
else if(mainMessageBox.getEnabled() == false && buttonNewGame.mouseClick(x, y)){
soundRenderer.playFx(coreData.getClickSoundB());
mainMenu->setState(new MenuStateNewGame(program, mainMenu));
@ -196,6 +282,195 @@ void MenuStateRoot::mouseClick(int x, int y, MouseButton mouseButton){
}
}
void MenuStateRoot::startFTPClientIfRequired() {
if(ftpClientThread == NULL) {
// Setup File Transfer thread
Config &config = Config::getInstance();
vector<string> tilesetFiles;
vector<string> tilesetFilesUserData;
vector<string> techTreeFiles;
vector<string> techTreeFilesUserData;
findDirs(config.getPathListForType(ptTilesets), tilesetFiles);
findDirs(config.getPathListForType(ptTechs), techTreeFiles);
vector<string> mapPathList = config.getPathListForType(ptMaps);
std::pair<string,string> mapsPath;
if(mapPathList.empty() == false) {
mapsPath.first = mapPathList[0];
}
if(mapPathList.size() > 1) {
mapsPath.second = mapPathList[1];
}
std::pair<string,string> tilesetsPath;
vector<string> tilesetsList = Config::getInstance().getPathListForType(ptTilesets);
if(tilesetsList.empty() == false) {
tilesetsPath.first = tilesetsList[0];
if(tilesetsList.size() > 1) {
tilesetsPath.second = tilesetsList[1];
}
}
std::pair<string,string> techtreesPath;
vector<string> techtreesList = Config::getInstance().getPathListForType(ptTechs);
if(techtreesList.empty() == false) {
techtreesPath.first = techtreesList[0];
if(techtreesList.size() > 1) {
techtreesPath.second = techtreesList[1];
}
}
std::pair<string,string> scenariosPath;
vector<string> scenariosList = Config::getInstance().getPathListForType(ptScenarios);
if(scenariosList.empty() == false) {
scenariosPath.first = scenariosList[0];
if(scenariosList.size() > 1) {
scenariosPath.second = scenariosList[1];
}
}
string fileArchiveExtension = config.getString("FileArchiveExtension","");
string fileArchiveExtractCommand = config.getString("FileArchiveExtractCommand","");
string fileArchiveExtractCommandParameters = config.getString("FileArchiveExtractCommandParameters","");
int32 fileArchiveExtractCommandSuccessResult = config.getInt("FileArchiveExtractCommandSuccessResult","0");
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
console.setOnlyChatMessagesInStoredLines(false);
// Get path to temp files
string tempFilePath = "temp/";
if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
tempFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + tempFilePath;
}
else {
string userData = config.getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
}
tempFilePath = userData + tempFilePath;
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Temp files path [%s]\n",tempFilePath.c_str());
ftpClientThread = new FTPClientThread(-1,"",
mapsPath,tilesetsPath,techtreesPath,scenariosPath,
this,fileArchiveExtension,fileArchiveExtractCommand,
fileArchiveExtractCommandParameters,
fileArchiveExtractCommandSuccessResult,
tempFilePath);
ftpClientThread->start();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}
void MenuStateRoot::FTPClient_CallbackEvent(string itemName,
FTP_Client_CallbackType type, pair<FTP_Client_ResultType,string> result,void *userdata) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) 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);
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),mutexOwnerId);
if(ftpClientThread != NULL && ftpClientThread->getProgressMutex() != NULL) ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId);
pair<int,string> lastProgress = fileFTPProgressList[itemName];
fileFTPProgressList[itemName] = pair<int,string>(fileProgress,stats->currentFilename);
safeMutexFTPProgress.ReleaseLock();
if(itemName != "" && (lastDownloadProgress < fileProgress && fileProgress % 25 == 0)) {
lastDownloadProgress = fileProgress;
char szBuf[8096]="";
snprintf(szBuf,8096,"Downloaded %d%% of file: %s",fileProgress,itemName.c_str());
console.addLine(szBuf);
}
}
}
else if(type == ftp_cct_ExtractProgress) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP extract Callback for [%s] result = %d [%s]\n",itemName.c_str(),result.first,result.second.c_str());
printf("Got FTP extract Callback for [%s] result = %d [%s]\n",itemName.c_str(),result.first,result.second.c_str());
if(userdata == NULL) {
char szBuf[8096]="";
snprintf(szBuf,8096,lang.getString("DataMissingExtractDownloadMod").c_str(),itemName.c_str());
//printf("%s\n",szBuf);
console.addLine(szBuf,true);
}
else {
char *szBuf = (char *)userdata;
//printf("%s\n",szBuf);
console.addLine(szBuf);
}
}
else if(type == ftp_cct_TempFile) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] result = %d [%s]\n",itemName.c_str(),result.first,result.second.c_str());
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),mutexOwnerId);
if(ftpClientThread != NULL && ftpClientThread->getProgressMutex() != NULL) ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId);
fileFTPProgressList.erase(itemName);
safeMutexFTPProgress.ReleaseLock();
printf("### downloaded TEMP file [%s] result = %d\n",itemName.c_str(),result.first);
if(result.first == ftp_crt_SUCCESS) {
// Get path to temp files
string tempFilePath = "temp/";
if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
tempFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + tempFilePath;
}
else {
Config &config = Config::getInstance();
string userData = config.getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
}
tempFilePath = userData + tempFilePath;
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Temp files path [%s]\n",tempFilePath.c_str());
// Delete the downloaded archive
if(fileExists(tempFilePath + itemName)) {
removeFile(tempFilePath + itemName);
}
// Move all files into binary folder
vector<string> fileList = getFolderTreeContentsListRecursively(tempFilePath, "", false, NULL);
for(unsigned int index = 0; index < fileList.size(); ++index) {
string fileName = fileList[index];
string newFileName = Properties::getApplicationPath() + extractFileFromDirectoryPath(fileName);
bool result = renameFile(fileName,newFileName);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Rename: [%s] to [%s] result = %d\n",fileName.c_str(),newFileName.c_str(),result);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Successfully updated!\n");
console.addLine("Successfully updated, please restart!",true);
}
else {
curl_version_info_data *curlVersion= curl_version_info(CURLVERSION_NOW);
char szBuf[8096]="";
snprintf(szBuf,8096,"FAILED to download the updates: [%s] using CURL version [%s] [%s]",itemName.c_str(),curlVersion->version,result.second.c_str());
console.addLine(szBuf,true);
showErrorMessageBox(szBuf, "ERROR", false);
}
}
}
void MenuStateRoot::mouseMove(int x, int y, const MouseState *ms){
popupMenu.mouseMove(x, y);
buttonNewGame.mouseMove(x, y);
@ -210,6 +485,9 @@ void MenuStateRoot::mouseMove(int x, int y, const MouseState *ms){
if (errorMessageBox.getEnabled()) {
errorMessageBox.mouseMove(x, y);
}
if (ftpMessageBox.getEnabled()) {
ftpMessageBox.mouseMove(x, y);
}
}
bool MenuStateRoot::isMasterserverMode() const {
@ -290,6 +568,9 @@ void MenuStateRoot::render() {
if(errorMessageBox.getEnabled()) {
renderer.renderMessageBox(&errorMessageBox);
}
if(ftpMessageBox.getEnabled()) {
renderer.renderMessageBox(&ftpMessageBox);
}
if(program != NULL) program->renderProgramMsgBox();
}
@ -304,9 +585,104 @@ void MenuStateRoot::update() {
}
return;
}
if(gameUpdateChecked == false) {
gameUpdateChecked = true;
string updateCheckURL = Config::getInstance().getString("UpdateCheckURL","");
if(updateCheckURL != "") {
static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__);
updatesHttpServerThread = new SimpleTaskThread(this,1,200);
updatesHttpServerThread->setUniqueID(mutexOwnerId);
updatesHttpServerThread->start();
}
}
console.update();
}
void MenuStateRoot::simpleTask(BaseThread *callingThread,void *userdata) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutexThreadOwner(callingThread->getMutexThreadOwnerValid(),mutexOwnerId);
if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
return;
}
callingThread->getMutexThreadOwnerValid()->setOwnerId(mutexOwnerId);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
string updateCheckURL = Config::getInstance().getString("UpdateCheckURL","");
if(updateCheckURL != "") {
string baseURL = updateCheckURL;
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] About to call first http url, base [%s]..\n",__FILE__,__FUNCTION__,__LINE__,baseURL.c_str());
CURL *handle = SystemFlags::initHTTP();
CURLcode curlResult = CURLE_OK;
string updateMetaData = SystemFlags::getHTTP(baseURL,handle,-1,&curlResult);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("techsMetaData [%s] curlResult = %d\n",updateMetaData.c_str(),curlResult);
if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
return;
}
if(curlResult != CURLE_OK) {
string curlError = curl_easy_strerror(curlResult);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] curlError [%s]..\n",__FILE__,__FUNCTION__,__LINE__,curlError.c_str());
char szMsg[8096]="";
snprintf(szMsg,8096,"An error was detected while checking for new updates\n%s",curlError.c_str());
showErrorMessageBox(szMsg, "ERROR", false);
}
if(curlResult == CURLE_OK ||
(curlResult != CURLE_COULDNT_RESOLVE_HOST &&
curlResult != CURLE_COULDNT_CONNECT)) {
Properties props;
props.loadFromText(updateMetaData);
int compareResult = compareMajorMinorVersion(glestVersionString, props.getString("LatestGameVersion",""),true);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("compareResult = %d local [%s] remote [%s]\n",compareResult,glestVersionString.c_str(),props.getString("LatestGameVersion","").c_str());
if(compareResult < 0) {
string downloadBinaryKey = "LatestGameBinaryUpdateArchiveURL-" + getPlatformTypeNameString() + getPlatformArchTypeNameString();
if(props.hasString(downloadBinaryKey)) {
ftpFileName = extractFileFromDirectoryPath(props.getString(downloadBinaryKey));
ftpFileURL = props.getString(downloadBinaryKey);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Checking update key downloadBinaryKey [%s] ftpFileURL [%s]\n",downloadBinaryKey.c_str(),ftpFileURL.c_str());
if(props.getBool("AllowUpdateDownloads","false") == false || ftpFileURL == "") {
char szMsg[8096]="";
snprintf(szMsg,8096,"A new update was detected: %s\nUpdate Date: %s\nPlease visit megaglest.org for details!",
props.getString("LatestGameVersion","?").c_str(),
props.getString("LatestGameVersionReleaseDate","?").c_str());
showFTPMessageBox(szMsg, "Update", false, true);
}
else {
char szMsg[8096]="";
snprintf(szMsg,8096,"A new update was detected: %s\nUpdate Date: %s\nDownload update now?",
props.getString("LatestGameVersion","?").c_str(),
props.getString("LatestGameVersionReleaseDate","?").c_str());
showFTPMessageBox(szMsg, "Update", false, false);
}
}
}
SystemFlags::cleanupHTTP(&handle);
}
}
void MenuStateRoot::keyDown(SDL_KeyboardEvent key) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym,key.keysym.sym);
@ -344,34 +720,58 @@ void MenuStateRoot::keyDown(SDL_KeyboardEvent key) {
}
void MenuStateRoot::showMessageBox(const string &text, const string &header, bool toggle){
if(!toggle){
void MenuStateRoot::showMessageBox(const string &text, const string &header, bool toggle) {
if(toggle == false) {
mainMessageBox.setEnabled(false);
}
if(!mainMessageBox.getEnabled()){
if(mainMessageBox.getEnabled() == false) {
mainMessageBox.setText(text);
mainMessageBox.setHeader(header);
mainMessageBox.setEnabled(true);
}
else{
else {
mainMessageBox.setEnabled(false);
}
}
void MenuStateRoot::showErrorMessageBox(const string &text, const string &header, bool toggle){
if(!toggle){
void MenuStateRoot::showErrorMessageBox(const string &text, const string &header, bool toggle) {
if(toggle == false) {
errorMessageBox.setEnabled(false);
}
if(!errorMessageBox.getEnabled()){
if(errorMessageBox.getEnabled() == false) {
errorMessageBox.setText(text);
errorMessageBox.setHeader(header);
errorMessageBox.setEnabled(true);
}
else{
else {
errorMessageBox.setEnabled(false);
}
}
void MenuStateRoot::showFTPMessageBox(const string &text, const string &header, bool toggle, bool okOnly) {
if(toggle == false) {
ftpMessageBox.setEnabled(false);
}
Lang &lang= Lang::getInstance();
if(okOnly) {
ftpMessageBox.init(lang.getString("Ok"));
}
else {
ftpMessageBox.init(lang.getString("Yes"), lang.getString("No"));
}
if(ftpMessageBox.getEnabled() == false) {
ftpMessageBox.setText(text);
ftpMessageBox.setHeader(header);
ftpMessageBox.setEnabled(true);
}
else {
ftpMessageBox.setEnabled(false);
}
}
}}//end namespace

View File

@ -13,6 +13,9 @@
#define _GLEST_GAME_MENUSTATEROOT_H_
#include "main_menu.h"
#include "simple_threads.h"
#include "miniftpclient.h"
#include "leak_dumper.h"
namespace Glest{ namespace Game{
@ -24,7 +27,7 @@ namespace Glest{ namespace Game{
class GraphicMessageBox;
class PopupMenu;
class MenuStateRoot: public MenuState {
class MenuStateRoot: public MenuState, public SimpleTaskCallbackInterface, public FTPClientCallbackInterface {
private:
GraphicButton buttonNewGame;
GraphicButton buttonLoadGame;
@ -36,20 +39,36 @@ private:
GraphicMessageBox mainMessageBox;
GraphicMessageBox errorMessageBox;
GraphicMessageBox ftpMessageBox;
PopupMenu popupMenu;
static bool gameUpdateChecked;
SimpleTaskThread *updatesHttpServerThread;
FTPClientThread *ftpClientThread;
std::map<string,pair<int,string> > fileFTPProgressList;
string ftpFileName;
string ftpFileURL;
int lastDownloadProgress;
virtual void simpleTask(BaseThread *callingThread,void *userdata);
void startFTPClientIfRequired();
virtual void FTPClient_CallbackEvent(string itemName,
FTP_Client_CallbackType type, pair<FTP_Client_ResultType,string> result,void *userdata);
public:
MenuStateRoot(Program *program, MainMenu *mainMenu);
virtual ~MenuStateRoot();
void mouseClick(int x, int y, MouseButton mouseButton);
void mouseMove(int x, int y, const MouseState *mouseState);
void render();
void update();
virtual void keyDown(SDL_KeyboardEvent key);
void showMessageBox(const string &text, const string &header, bool toggle);
void showMessageBox(const string &text, const string &header, bool toggle);
void showErrorMessageBox(const string &text, const string &header, bool toggle);
void showFTPMessageBox(const string &text, const string &header, bool toggle, bool okOnly);
virtual bool isMasterserverMode() const;
virtual void reloadUI();

View File

@ -2692,14 +2692,16 @@ const Resource *World::getResourceForTeam(const ResourceType *rt, int teamIndex)
Faction *faction = factions[index];
if(faction != NULL && faction->getTeam() == teamIndex) {
const Resource *factionResource = faction->getResource(rt,true);
if(factionResource != NULL && factionResource->getType() != NULL) {
if(faction->hasAliveUnits(true,true)) {
const Resource *factionResource = faction->getResource(rt,true);
if(factionResource != NULL && factionResource->getType() != NULL) {
int teamResourceAmount = teamResource.getAmount();
int teamResourceBalance = teamResource.getBalance();
int teamResourceAmount = teamResource.getAmount();
int teamResourceBalance = teamResource.getBalance();
teamResource.setAmount(teamResourceAmount + factionResource->getAmount());
teamResource.setBalance(teamResourceBalance + factionResource->getBalance());
teamResource.setAmount(teamResourceAmount + factionResource->getAmount());
teamResource.setBalance(teamResourceBalance + factionResource->getBalance());
}
}
}
}

View File

@ -54,6 +54,9 @@ private:
static string scenarioPath;
static string tutorialPath;
protected:
void processTextLine(bool is_utf8_language, char *lineBuffer);
public:
static void setApplicationPath(string value) { applicationPath=value; }
static string getApplicationPath() { return applicationPath; }
@ -72,6 +75,8 @@ public:
static string getTutorialPath() { return tutorialPath; }
void clear();
void loadFromText(const string &text);
void load(const string &path,bool clearCurrentProperties=true);
void save(const string &path);

View File

@ -239,7 +239,7 @@ float saturate(float value);
int round(float f);
//misc
int compareMajorMinorVersion(string versionA,string versionB);
int compareMajorMinorVersion(string versionA,string versionB, bool checkForNewVersionUpdates=false);
int getMajor(string version);
int getMinor(string version);
bool checkVersionComptability(string clientVersionString, string serverVersionString);

View File

@ -845,6 +845,8 @@ pair<FTP_Client_ResultType,string> FTPClientThread::getFileInternalFromServer(p
pair<FTP_Client_ResultType,string> result = getFileFromServer(ftp_cct_File,
fileName,remotePath, destFileSaveAs, "", "");
//printf("Got file [%s] result.first = %d\n",destFileSaveAs.c_str(),result.first);
// Extract the archive
if(result.first == ftp_crt_SUCCESS) {
string ext = extractExtension(destFileSaveAs);
@ -897,10 +899,18 @@ pair<FTP_Client_ResultType,string> FTPClientThread::getTempFileInternalFromServ
destFileSaveAs += fileName.first;
string remotePath = fileName.second;
fileName.second = "";
pair<FTP_Client_ResultType,string> result = getFileFromServer(ftp_cct_TempFile,
fileName,remotePath, destFileSaveAs, FTP_TEMPFILES_USERNAME, FTP_COMMON_PASSWORD);
//printf("First [%s] Second [%s]\n",fileName.first.c_str(),fileName.second.c_str());
pair<FTP_Client_ResultType,string> result;
if(StartsWith(remotePath,"http://")) {
result = getFileFromServer(ftp_cct_TempFile, fileName,remotePath, destFileSaveAs, "", "");
}
else {
fileName.second = "";
result = getFileFromServer(ftp_cct_TempFile,fileName,remotePath, destFileSaveAs, FTP_TEMPFILES_USERNAME, FTP_COMMON_PASSWORD);
}
//printf("Got temp file [%s] result.first = %d\n",destFileSaveAs.c_str(),result.first);
// Extract the archive
if(result.first == ftp_crt_SUCCESS) {

View File

@ -14,6 +14,8 @@
#include <fstream>
#include <stdexcept>
#include <cstring>
#include <iostream>
#include <sstream>
#include "conversion.h"
#include "util.h"
@ -31,7 +33,6 @@
#include "utf8.h"
#include "font.h"
#include "string_utils.h"
#include "leak_dumper.h"
using namespace std;
@ -56,8 +57,6 @@ string Properties::tutorialPath = "";
void Properties::load(const string &path, bool clearCurrentProperties) {
char lineBuffer[maxLine]="";
string line, key, value, original_value;
size_t pos=0;
this->path= path;
bool is_utf8_language = valid_utf8_file(path.c_str());
@ -88,80 +87,7 @@ void Properties::load(const string &path, bool clearCurrentProperties) {
fileStream.getline(lineBuffer, maxLine);
lineBuffer[maxLine-1]='\0';
//printf("\n[%ls]\n",lineBuffer);
//printf("\n[%s]\n",&lineBuffer[0]);
if(lineBuffer[0] != '\0') {
// If the file is NOT in UTF-8 format convert each line
if(is_utf8_language == false && Font::forceLegacyFonts == false) {
char *utfStr = ConvertToUTF8(&lineBuffer[0]);
//printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr);
memset(&lineBuffer[0],0,maxLine);
memcpy(&lineBuffer[0],&utfStr[0],strlen(utfStr));
delete [] utfStr;
}
else if(is_utf8_language == true && Font::forceLegacyFonts == true) {
char *asciiStr = ConvertFromUTF8(&lineBuffer[0]);
//printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr);
memset(&lineBuffer[0],0,maxLine);
memcpy(&lineBuffer[0],&asciiStr[0],strlen(asciiStr));
delete [] asciiStr;
}
}
//process line if it it not a comment
if(lineBuffer[0] != ';' && lineBuffer[0] != '#') {
//wstring wstr = lineBuffer;
//line.assign(wstr.begin(),wstr.end());
// gracefully handle win32 \r\n line endings
size_t len= strlen(lineBuffer);
if(len > 0 && lineBuffer[len-1] == '\r') {
lineBuffer[len-1]= 0;
}
line= lineBuffer;
pos= line.find('=');
if(pos != string::npos){
key= line.substr(0, pos);
value= line.substr(pos+1);
original_value = value;
if(applyTagsToValue(value) == true) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Property key [%s] now has value [%s] original_value [%s]\n",key.c_str(),value.c_str(),original_value.c_str());
}
bool replaceExisting = false;
if(propertyMap.find(key) != propertyMap.end()) {
replaceExisting = true;
}
propertyMap[key] = original_value;
propertyMapTmp[key] = value;
if(replaceExisting == false) {
propertyVector.push_back(PropertyPair(key, original_value));
propertyVectorTmp.push_back(PropertyPair(key, value));
}
else {
for(unsigned int i = 0; i < propertyVector.size(); ++i) {
PropertyPair &currentPair = propertyVector[i];
if(currentPair.first == key) {
currentPair.second = original_value;
propertyVectorTmp[i].second = value;
break;
}
}
}
}
}
processTextLine(is_utf8_language,lineBuffer);
}
fileStream.close();
@ -172,6 +98,108 @@ void Properties::load(const string &path, bool clearCurrentProperties) {
#endif
}
void Properties::loadFromText(const string &text) {
bool is_utf8_language = false;
char lineBuffer[maxLine]="";
std::istringstream textStream(text);
while(textStream.eof() == false) {
//lineBuffer[0]='\0';
std::string lineText;
getline(textStream, lineText);
if(lineText.length() > 0) {
memset(&lineBuffer[0],0,maxLine);
memcpy(&lineBuffer[0],&lineText[0],lineText.length());
//fileStream.getline(lineBuffer, maxLine);
//lineBuffer[maxLine-1]='\0';
processTextLine(is_utf8_language,&lineBuffer[0]);
}
}
}
void Properties::processTextLine(bool is_utf8_language, char *lineBuffer) {
//printf("\n[%ls]\n",lineBuffer);
//printf("\n[%s]\n",&lineBuffer[0]);
string line, key, value, original_value;
size_t pos=0;
if(lineBuffer != NULL && lineBuffer[0] != '\0') {
// If the file is NOT in UTF-8 format convert each line
if(is_utf8_language == false && Font::forceLegacyFonts == false) {
char *utfStr = ConvertToUTF8(&lineBuffer[0]);
//printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr);
memset(&lineBuffer[0],0,maxLine);
memcpy(&lineBuffer[0],&utfStr[0],strlen(utfStr));
delete [] utfStr;
}
else if(is_utf8_language == true && Font::forceLegacyFonts == true) {
char *asciiStr = ConvertFromUTF8(&lineBuffer[0]);
//printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr);
memset(&lineBuffer[0],0,maxLine);
memcpy(&lineBuffer[0],&asciiStr[0],strlen(asciiStr));
delete [] asciiStr;
}
}
//process line if it it not a comment
if(lineBuffer != NULL && lineBuffer[0] != ';' && lineBuffer[0] != '#') {
//wstring wstr = lineBuffer;
//line.assign(wstr.begin(),wstr.end());
// gracefully handle win32 \r\n line endings
size_t len= strlen(lineBuffer);
if(len > 0 && lineBuffer[len-1] == '\r') {
lineBuffer[len-1]= 0;
}
line= lineBuffer;
pos= line.find('=');
if(pos != string::npos){
key= line.substr(0, pos);
value= line.substr(pos+1);
original_value = value;
if(applyTagsToValue(value) == true) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Property key [%s] now has value [%s] original_value [%s]\n",key.c_str(),value.c_str(),original_value.c_str());
}
bool replaceExisting = false;
if(propertyMap.find(key) != propertyMap.end()) {
replaceExisting = true;
}
propertyMap[key] = original_value;
propertyMapTmp[key] = value;
if(replaceExisting == false) {
propertyVector.push_back(PropertyPair(key, original_value));
propertyVectorTmp.push_back(PropertyPair(key, value));
}
else {
for(unsigned int i = 0; i < propertyVector.size(); ++i) {
PropertyPair &currentPair = propertyVector[i];
if(currentPair.first == key) {
currentPair.second = original_value;
propertyVectorTmp[i].second = value;
break;
}
}
}
}
}
}
std::map<string,string> Properties::getTagReplacementValues(std::map<string,string> *mapExtraTagReplacementValues) {
std::map<string,string> mapTagReplacementValues;

View File

@ -787,54 +787,70 @@ int round(float f){
}
// ==================== misc ====================
int compareMajorMinorVersion(string versionA,string versionB){
int majorA=getMajor(versionA);
int minorA=getMinor(versionA);
int majorB=getMajor(versionB);
int minorB=getMinor(versionB);
int compareMajorMinorVersion(string versionA,string versionB, bool checkForNewVersionUpdates) {
int majorA = getMajor(versionA);
int minorA = getMinor(versionA);
int majorB = getMajor(versionB);
int minorB = getMinor(versionB);
if(majorA<majorB) return -1;
else if(majorA==majorB){
if(minorA<minorB) return -1;
else if(minorA==minorB){
if(majorA < majorB) {
return -1;
}
else if(majorA == majorB) {
if(minorA < minorB) {
return -1;
}
else if(minorA == minorB) {
if(checkForNewVersionUpdates) {
if(versionA != versionB) {
return -1;
}
}
return 0;
}
else{
else {
return 1;
}
}
else{
else {
return 1;
}
}
int getMajor(string version){
vector<string> parts=split(version.substr(1),".");
int getMajor(string version) {
vector<string> parts = split(version.substr(1),".");
if(parts.size()>2 && parts[0] != "" && IsNumeric(parts[0].c_str(),false))
if(parts.size() > 2 && parts[0] != "" && IsNumeric(parts[0].c_str(),false)) {
return strToInt(parts[0]);
else
}
else {
return 0;
}
}
int getMinor(string version){
vector<string> parts=split(version.substr(1),".");
if(parts.size()>2 && parts[1] != ""){
int getMinor(string version) {
vector<string> parts = split(version.substr(1),".");
if(parts.size() > 2 && parts[1] != "") {
string resultStr="";
for (int i = 0; i < (int)parts[1].length(); ++i) {
// just add leading numbers
if(IsNumeric((resultStr+parts[1][i]).c_str(),false) )
if(IsNumeric((resultStr + parts[1][i]).c_str(),false) ) {
resultStr += parts[1][i];
else
}
else {
break;
}
}
if(resultStr=="")
if(resultStr == "") {
return 0;
else
}
else {
return strToInt(resultStr);
}
}
else
else {
return 0;
}
}
bool checkVersionComptability(string clientVersionString, string serverVersionString) {