diff --git a/source/glest_game/ai/ai_interface.cpp b/source/glest_game/ai/ai_interface.cpp index 85832b8b4..bc02475ba 100644 --- a/source/glest_game/ai/ai_interface.cpp +++ b/source/glest_game/ai/ai_interface.cpp @@ -553,7 +553,7 @@ namespace std::pair < CommandResult, string > result(crFailUndefined, ""); if (unit == NULL) { - printf("In [%s::%s Line: %d] Can not find AI unit in AI factionIndex = %d. Game out of synch.", + printf("In [%s::%s Line: %d] Can not find AI unit in AI factionIndex = %d. Game out of sync.\n", __FILE__, __FUNCTION__, __LINE__, factionIndex); /*throw megaglest_runtime_error(szBuf);*/ @@ -565,14 +565,14 @@ namespace const UnitType * unitType = unit->getType(); if (unitType == NULL) { - printf("In [%s::%s Line: %d] Can not find AI unittype with unit id: %d, AI factionIndex = %d. Game out of synch.", + printf("In [%s::%s Line: %d] Can not find AI unittype with unit id: %d, AI factionIndex = %d. Game out of sync.\n", __FILE__, __FUNCTION__, __LINE__, unit->getId(), factionIndex); /*throw megaglest_runtime_error(szBuf);*/ return result; } if (commandType == NULL) { - printf("In [%s::%s Line: %d] commandType == NULL, unit id: %d, AI factionIndex = %d. Game out of synch.", + printf("In [%s::%s Line: %d] commandType == NULL, unit id: %d, AI factionIndex = %d. Game out of sync.\n", __FILE__, __FUNCTION__, __LINE__, unit->getId(), factionIndex); /*throw @@ -585,7 +585,7 @@ namespace char szBuf[8096] = ""; snprintf(szBuf, 8096, - "In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", + "In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of sync.\n", __FILE__, __FUNCTION__, __LINE__, unit->getId(), unit->getFullName(false).c_str(), unit->getDesc(false).c_str(), @@ -647,7 +647,7 @@ namespace const Unit * unit = getMyUnit(unitIndex); if (unit == NULL) { - printf("In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch.", + printf("In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of sync.\n", __FILE__, __FUNCTION__, __LINE__, unitIndex, factionIndex); /*throw @@ -660,7 +660,7 @@ namespace const UnitType * unitType = unit->getType(); if (unitType == NULL) { - printf("In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch.", + printf("In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of sync.\n", __FILE__, __FUNCTION__, __LINE__, unitIndex, factionIndex); /*throw @@ -734,7 +734,7 @@ namespace const Unit * unit = getMyUnit(unitIndex); if (unit == NULL) { - printf("In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch.", + printf("In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of sync.\n", __FILE__, __FUNCTION__, __LINE__, unitIndex, factionIndex); /*throw @@ -747,7 +747,7 @@ namespace const UnitType * unitType = unit->getType(); if (unitType == NULL) { - printf("In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch.", + printf("In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of sync.\n", __FILE__, __FUNCTION__, __LINE__, unitIndex, factionIndex); /*throw @@ -823,7 +823,7 @@ namespace const Unit * unit = getMyUnit(unitIndex); if (unit == NULL) { - printf("In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch.", + printf("In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of sync.\n", __FILE__, __FUNCTION__, __LINE__, unitIndex, factionIndex); /*throw @@ -836,7 +836,7 @@ namespace const UnitType * unitType = unit->getType(); if (unitType == NULL) { - printf("In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch.", + printf("In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of sync.\n", __FILE__, __FUNCTION__, __LINE__, unitIndex, factionIndex); /*throw diff --git a/source/glest_game/game/commander.cpp b/source/glest_game/game/commander.cpp index 18193ca89..4bb5dfa22 100644 --- a/source/glest_game/game/commander.cpp +++ b/source/glest_game/game/commander.cpp @@ -664,20 +664,15 @@ namespace nctDisconnectNetworkPlayer) { unit = world->findUnitById(networkCommand->getUnitId()); if (unit == NULL) { - char - szBuf[8096] = ""; - snprintf(szBuf, 8096, - "In [%s::%s - %d] Command refers to non existent unit id = %d. Game out of sync", - extractFileFromDirectoryPath(__FILE__).c_str(), - __FUNCTION__, __LINE__, networkCommand->getUnitId()); + char szMsg[8096] = ""; + snprintf(szMsg, 8096, "Error: Command refers to non-existent unit id %d. Game out of sync, try leaving and rejoining", + networkCommand->getUnitId()); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szMsg); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", szMsg); GameNetworkInterface * gameNetworkInterface = NetworkManager::getInstance().getGameNetworkInterface(); if (gameNetworkInterface != NULL) { - char - szMsg[8096] = ""; - snprintf(szMsg, 8096, "Error: Command refers to non-existent unit id %d. Game out of sync, try leaving and rejoining", - networkCommand->getUnitId()); gameNetworkInterface-> sendTextMessage(szMsg, -1, true, ""); } @@ -1612,29 +1607,16 @@ namespace // Validate unit is in game. if (unit == NULL) { - char - szBuf[8096] = ""; - snprintf(szBuf, 8096, - "In [%s::%s Line: %d] Can not find unit with id: %d. Game out of synch.", - extractFileFromDirectoryPath(__FILE__).c_str(), - __FUNCTION__, __LINE__, networkCommand->getUnitId()); - SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szBuf); - if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", - szBuf); - + char szMsg[8096] = ""; + snprintf(szMsg, 8096, "Error: Cannot find unit with id %d. Game out of sync, try leaving and rejoining", + networkCommand->getUnitId()); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szMsg); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", szMsg); GameNetworkInterface * gameNetworkInterface = NetworkManager::getInstance().getGameNetworkInterface(); - if (gameNetworkInterface != NULL) { - char - szMsg[8096] = ""; - snprintf(szMsg, 8096, - "Error: Cannot find unit with id %d. Game out of sync, try leaving and rejoining", - networkCommand->getUnitId()); + if (gameNetworkInterface != NULL) gameNetworkInterface->sendTextMessage(szMsg, -1, true, ""); - } /*throw megaglest_runtime_error(szBuf);*/ @@ -1649,44 +1631,23 @@ namespace // Check that the unit from the network command is the same faction as the unit in the local game. if (unit->getFaction()->getIndex() != networkCommand->getUnitFactionIndex()) { - - char - szBuf[8096] = ""; - snprintf(szBuf, 8096, - "In [%s::%s Line: %d]\nUnit/Faction mismatch for network command = [%s]\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of sync", - __FILE__, __FUNCTION__, __LINE__, - networkCommand->toString().c_str(), - unit->getId(), unit->getFullName(false).c_str(), - unit->getDesc(false).c_str(), - unit->getFaction()->getIndex()); - - SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szBuf); - if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", - szBuf); - + char szMsg[8096] = ""; + snprintf(szMsg, 8096, + "Error: Unit/Faction mismatch for unitId %d, local faction index %d, remote index %d. Game out of sync, try leaving and rejoining", + networkCommand->getUnitId(), + unit->getFaction()->getIndex(), + networkCommand->getUnitFactionIndex()); + + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szMsg); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", szMsg); //world->DumpWorldToLog(); // Broadcast the error if player is still connected and print locally. GameNetworkInterface * gameNetworkInterface = NetworkManager::getInstance().getGameNetworkInterface(); - if (gameNetworkInterface != NULL) { - char szMsg[8096] = ""; - snprintf(szMsg, 8096, - "Error: Unit/Faction mismatch for unitId %d, local faction index %d, remote index %d. Game out of sync, try leaving and rejoining", - networkCommand->getUnitId(), - unit->getFaction()->getIndex(), - networkCommand->getUnitFactionIndex()); + if (gameNetworkInterface != NULL) gameNetworkInterface->sendTextMessage(szMsg, -1, true, ""); - } - - /*// Kill the game. - std::string sError = - "Error [#1]: Game is out of sync (Unit / Faction mismatch)\nplease check log files for details."; - throw - megaglest_runtime_error(sError);*/ return command; } @@ -1714,41 +1675,23 @@ namespace // Throw an error if a valid command for the unit is still not found. if (ct == NULL) { - char - szBuf[8096] = ""; - snprintf(szBuf, 8096, - "In [%s::%s Line: %d]\nCannot find command type for network command = [%s]\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nUnit Type Info:\n[%s]\nNetwork unit type:\n[%s]\nGame out of sync", - extractFileFromDirectoryPath(__FILE__).c_str(), - __FUNCTION__, __LINE__, - networkCommand->toString().c_str(), - unit->getId(), unit->getFullName(false).c_str(), - unit->getDesc(false).c_str(), - unit->getFaction()->getIndex(), - unit->getType()->toString().c_str(), + char szMsg[8096] = ""; + snprintf(szMsg, 8096, "Error: Cannot find command type %d for unitId %d [%s]. Game out of sync, try leaving and rejoining", + networkCommand->getCommandTypeId(), + networkCommand->getUnitId(), (unitType != NULL ? unitType->getName(false).c_str() : "null")); - SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", szBuf); - SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szBuf); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", szMsg); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szMsg); //world->DumpWorldToLog(); GameNetworkInterface * gameNetworkInterface = NetworkManager::getInstance().getGameNetworkInterface(); - if (gameNetworkInterface != NULL) { - char szMsg[8096] = ""; - snprintf(szMsg, 8096, "Error: Cannot find command type %d for unitId %d [%s]. Game out of sync, try leaving and rejoining", - networkCommand->getCommandTypeId(), - networkCommand->getUnitId(), - (unitType != - NULL ? unitType->getName(false).c_str() : "null")); + if (gameNetworkInterface != NULL) gameNetworkInterface->sendTextMessage(szMsg, -1, true, ""); - } - /*std::string sError = - "Error [#3]: Game is out of sync, please check log files for details."; - throw - megaglest_runtime_error(sError);*/ return command; } diff --git a/source/glest_game/global/core_data.cpp b/source/glest_game/global/core_data.cpp index d9d712d37..d058abb04 100644 --- a/source/glest_game/global/core_data.cpp +++ b/source/glest_game/global/core_data.cpp @@ -1783,8 +1783,8 @@ namespace Glest { StaticSound *PlaySoundClip::getSound(const std::string& playSoundVal) { static int soundCtr = 0; if (alertSoundMap.find(playSoundVal) == alertSoundMap.end()) { - alertSoundMap[playSoundVal] = soundCtr; - playSound.resize(soundCtr + 1); + alertSoundMap[playSoundVal] = soundCtr; + playSound.resize(soundCtr + 1); try { CoreData & coreData = CoreData::getInstance(); string data_path = coreData.getDataPath(); diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 637a3136e..bed70c477 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -37,6 +37,7 @@ #include "platform_util.h" #include "platform_main.h" #include "network_interface.h" +#include "network_manager.h" #include "ImageReaders.h" #include "renderer.h" #include "simple_threads.h" @@ -99,14 +100,19 @@ #endif using namespace std; -using namespace -Shared::Platform; +using namespace Shared::Platform; using namespace Shared::Util; using namespace Shared::Graphics; using namespace Shared::Graphics::Gl; using namespace Shared::Xml; using namespace Shared; +void handleUnexpectedError(const char* message) { + Glest::Game::GameNetworkInterface* gameNetworkInterface = Glest::Game::NetworkManager::getInstance().getGameNetworkInterface(); + if (gameNetworkInterface != NULL) + gameNetworkInterface->sendTextMessage(message, -1, true, ""); +} + /** * @namespace Glest * Namespace used for all %Glest related code. @@ -1082,6 +1088,7 @@ namespace this->triggerLanguageToggle = false; this->triggerLanguage = ""; this->cancelLanguageSelection = -1; + setUnexpectedHandler(&handleUnexpectedError); } MainWindow::~MainWindow() { diff --git a/source/shared_lib/include/platform/common/platform_common.h b/source/shared_lib/include/platform/common/platform_common.h index 585c4fcec..3c2423211 100644 --- a/source/shared_lib/include/platform/common/platform_common.h +++ b/source/shared_lib/include/platform/common/platform_common.h @@ -203,6 +203,8 @@ namespace Shared { string getCRCCacheFilePath(); void setCRCCacheFilePath(const string &path); + void setUnexpectedHandler(void(*handler)(const char*)); + std::pair getFolderTreeContentsCheckSumCacheKey(vector paths, const string &pathSearchString, const string &filterFileExt); void clearFolderTreeContentsCheckSum(vector paths, const string &pathSearchString, const string &filterFileExt); uint32 getFolderTreeContentsCheckSumRecursively(vector paths, string pathSearchString, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache = false); diff --git a/source/shared_lib/sources/platform/common/platform_common.cpp b/source/shared_lib/sources/platform/common/platform_common.cpp index e14817db7..a3be5d2b3 100644 --- a/source/shared_lib/sources/platform/common/platform_common.cpp +++ b/source/shared_lib/sources/platform/common/platform_common.cpp @@ -90,14 +90,13 @@ using namespace Shared::Platform; using namespace Shared::Util; using namespace std; -#define _DISABLE_MEMORY_VAULT_CHECKS 1 +//#define _DISABLE_MEMORY_VAULT_CHECKS 1 namespace Shared { namespace PlatformCommon { - const time_t REFRESH_CRC_DAY_SECONDS = 60 * 60 * 24; static string crcCachePath = ""; - + static void(*unexpected_handler)(const char*) = NULL; static string gameVersion = ""; static string gameGITVersion = ""; @@ -684,6 +683,10 @@ namespace Shared { crcCachePath = path; } + void setUnexpectedHandler(void(*handler)(const char*)) { + unexpected_handler = handler; + } + //string getGameVersion() { // return gameVersion; //} @@ -2237,45 +2240,41 @@ namespace Shared { return intToStr(width) + "x" + intToStr(height) + "-" + intToStr(depth); } + void notifyValueChangedUnexpectedly() { + //if(SystemFlags::VERBOSE_MODE_ENABLED) { + // printf("In [%s::%s Line: %d] check vault key [%p] value [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,value); + // for(map::const_iterator iterFind = vaultList.begin(); + // iterFind != vaultList.end(); iterFind++) { + // printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); + // } + //} + + const char* szMsg = "A value in memory has changed unexpectedly. Game out of sync, try leaving and rejoining"; + printf("%s\n", szMsg); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", szMsg); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szMsg); + void(*handler)(const char*) = unexpected_handler; + if (handler != NULL) + handler(szMsg); + } + void ValueCheckerVault::addItemToVault(const void *ptr, int value) { #ifndef _DISABLE_MEMORY_VAULT_CHECKS - Checksum checksum; vaultList[ptr] = checksum.addInt(value); #endif - - // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] add vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value); } void ValueCheckerVault::checkItemInVault(const void *ptr, int value) const { #ifndef _DISABLE_MEMORY_VAULT_CHECKS - map::const_iterator iterFind = vaultList.find(ptr); - if (iterFind == vaultList.end()) { - // if(SystemFlags::VERBOSE_MODE_ENABLED) { - // printf("In [%s::%s Line: %d] check vault key [%p] value [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,value); - // for(map::const_iterator iterFind = vaultList.begin(); - // iterFind != vaultList.end(); iterFind++) { - // printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); - // } - // } - throw std::runtime_error("memory value has been unexpectedly modified (not found)!"); - } + if (iterFind == vaultList.end()) + notifyValueChangedUnexpectedly(); Checksum checksum; - if (iterFind->second != checksum.addInt(value)) { - // if(SystemFlags::VERBOSE_MODE_ENABLED) { - // printf("In [%s::%s Line: %d] check vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value); - // for(map::const_iterator iterFind = vaultList.begin(); - // iterFind != vaultList.end(); iterFind++) { - // printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); - // } - // } - throw std::runtime_error("memory value has been unexpectedly modified (changed)!"); - } - + if (iterFind->second != checksum.addInt(value)) + notifyValueChangedUnexpectedly(); #endif - } string getUserHome() {