From bf5f6b7f33c0698e9ac58629c7996f68bc4159cb Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Sun, 22 Aug 2010 08:00:05 +0000 Subject: [PATCH] - experimental support for idenitfying specific game data which is out of synch with the server. --- .../menu/menu_state_connected_game.cpp | 73 +++- .../menu/menu_state_connected_game.h | 4 + .../menu/menu_state_custom_game.cpp | 76 ++++- .../glest_game/menu/menu_state_custom_game.h | 4 + .../glest_game/network/client_interface.cpp | 62 ++-- source/glest_game/network/connection_slot.cpp | 47 ++- source/glest_game/network/network_interface.h | 8 + source/glest_game/network/network_message.cpp | 313 ++++++++++++++++-- source/glest_game/network/network_message.h | 90 +++-- .../glest_game/network/server_interface.cpp | 2 +- .../platform/common/platform_common.cpp | 20 +- 11 files changed, 586 insertions(+), 113 deletions(-) diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 773b4f9aa..a62724ae6 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -48,6 +48,7 @@ struct FormatString { MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainMenu,JoinMenu joinMenuInfo, bool openNetworkSlots): MenuState(program, mainMenu, "connected-game") //← set on connected-game { + updateDataSynchDetailText = false; activeInputLabel = NULL; lastNetworkSendPing = 0; pingCount = 0; @@ -260,7 +261,7 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ { if(clientInterface->isConnected() == true) { - string sQuitText = "has chosen to leave the game!"; + string sQuitText = "chose to leave the game!"; clientInterface->sendTextMessage(sQuitText,-1); sleep(1); } @@ -502,32 +503,73 @@ void MenuStateConnectedGame::update() if(clientInterface != NULL && clientInterface->isConnected()) { buttonDisconnect.setText(lang.get("Disconnect")); - if(clientInterface->getAllowDownloadDataSynch() == false) - { + if(clientInterface->getAllowDownloadDataSynch() == false) { string label = lang.get("ConnectedToServer"); - if(!clientInterface->getServerName().empty()) - { + if(!clientInterface->getServerName().empty()) { label = label + " " + clientInterface->getServerName(); } label = label + ", " + clientInterface->getVersionString(); if(clientInterface->getAllowGameDataSynchCheck() == true && - clientInterface->getNetworkGameDataSynchCheckOk() == false) - { - label = label + " - warning synch mismatch for:"; - if(clientInterface->getNetworkGameDataSynchCheckOkMap() == false) - { + clientInterface->getNetworkGameDataSynchCheckOk() == false) { + label = label + " -synch mismatch for:"; + + if(clientInterface->getNetworkGameDataSynchCheckOkMap() == false) { label = label + " map"; + + if(updateDataSynchDetailText == true && + clientInterface->getReceivedDataSynchCheck() && + lastMapDataSynchError != "map CRC mismatch") { + lastMapDataSynchError = "map CRC mismatch"; + clientInterface->sendTextMessage(lastMapDataSynchError,-1,true); + } } - if(clientInterface->getNetworkGameDataSynchCheckOkTile() == false) - { + else { + lastMapDataSynchError = ""; + } + + if(clientInterface->getNetworkGameDataSynchCheckOkTile() == false) { label = label + " tile"; + if(updateDataSynchDetailText == true && + clientInterface->getReceivedDataSynchCheck() && + lastTileDataSynchError != "tile CRC mismatch") { + lastTileDataSynchError = "tile CRC mismatch"; + clientInterface->sendTextMessage(lastTileDataSynchError,-1,true); + } } - if(clientInterface->getNetworkGameDataSynchCheckOkTech() == false) - { + else { + lastTileDataSynchError = ""; + } + + if(clientInterface->getNetworkGameDataSynchCheckOkTech() == false) { label = label + " techtree"; + + if(updateDataSynchDetailText == true && + clientInterface->getReceivedDataSynchCheck()) { + + string report = clientInterface->getNetworkGameDataSynchCheckTechMismatchReport(); + if(lastTechtreeDataSynchError != "techtree CRC mismatch" + report) { + lastTechtreeDataSynchError = "techtree CRC mismatch" + report; + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] report: %s\n",__FILE__,__FUNCTION__,__LINE__,report.c_str()); + + clientInterface->sendTextMessage("techtree CRC mismatch",-1,true); + vector reportLineTokens; + Tokenize(report,reportLineTokens,"\n"); + for(int reportLine = 0; reportLine < reportLineTokens.size(); ++reportLine) { + clientInterface->sendTextMessage(reportLineTokens[reportLine],-1,true); + } + } + } + } + else { + lastTechtreeDataSynchError = ""; + } + + if(clientInterface->getReceivedDataSynchCheck() == true) { + updateDataSynchDetailText = false; } //if(clientInterface->getNetworkGameDataSynchCheckOkFogOfWar() == false) //{ @@ -561,7 +603,7 @@ void MenuStateConnectedGame::update() if(clientInterface->getAllowGameDataSynchCheck() == true && clientInterface->getNetworkGameDataSynchCheckOk() == false) { - label = label + " - waiting to synch:"; + label = label + " -waiting to synch:"; if(clientInterface->getNetworkGameDataSynchCheckOkMap() == false) { label = label + " map"; @@ -610,6 +652,7 @@ void MenuStateConnectedGame::update() if(clientInterface->isConnected()) { bool mustSwitchPlayerName = false; if(clientInterface->getGameSettingsReceived()){ + updateDataSynchDetailText = true; bool errorOnMissingData = (clientInterface->getAllowGameDataSynchCheck() == false); //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); vector maps,tilesets,techtree; diff --git a/source/glest_game/menu/menu_state_connected_game.h b/source/glest_game/menu/menu_state_connected_game.h index 55206f70d..d81ae6a1d 100644 --- a/source/glest_game/menu/menu_state_connected_game.h +++ b/source/glest_game/menu/menu_state_connected_game.h @@ -79,6 +79,7 @@ private: bool needToSetChangedGameSettings; time_t lastSetChangedGameSettings; + bool updateDataSynchDetailText; Console console; ChatManager chatManager; @@ -92,6 +93,9 @@ private: int pingCount; bool initialSettingsReceivedFromServer; + string lastMapDataSynchError; + string lastTileDataSynchError; + string lastTechtreeDataSynchError; public: MenuStateConnectedGame(Program *program, MainMenu *mainMenu, JoinMenu joinMenuInfo=jmSimple, bool openNetworkSlots= false); diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index 6d9f1e1e9..4f77ec7a1 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -955,7 +955,7 @@ void MenuStateCustomGame::update() { //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] A - ctNetwork\n",__FILE__,__FUNCTION__); - if(connectionSlot->isConnected()) { + if(connectionSlot != NULL && connectionSlot->isConnected()) { connectionSlot->setName(labelPlayerNames[i].getText()); //printf("FYI we have at least 1 client connected, slot = %d'\n",i); @@ -966,12 +966,13 @@ void MenuStateCustomGame::update() { //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] B - ctNetwork\n",__FILE__,__FUNCTION__); string label = connectionSlot->getName() + ", " + connectionSlot->getVersionString(); - if(connectionSlot->getAllowDownloadDataSynch() == true && + if(connectionSlot != NULL && + connectionSlot->getAllowDownloadDataSynch() == true && connectionSlot->getAllowGameDataSynchCheck() == true) { if(connectionSlot->getNetworkGameDataSynchCheckOk() == false) { - label += " - waiting to synch:"; + label += " -waiting to synch:"; if(connectionSlot->getNetworkGameDataSynchCheckOkMap() == false) { label = label + " map"; @@ -994,21 +995,76 @@ void MenuStateCustomGame::update() { { //label = connectionSlot->getName(); - if(connectionSlot->getAllowGameDataSynchCheck() == true && + connectionSlot= serverInterface->getSlot(i); + if(connectionSlot != NULL && + connectionSlot->getAllowGameDataSynchCheck() == true && connectionSlot->getNetworkGameDataSynchCheckOk() == false) { - label += " - warning synch mismatch for:"; - if(connectionSlot->getNetworkGameDataSynchCheckOkMap() == false) - { + label += " -synch mismatch:"; + connectionSlot= serverInterface->getSlot(i); + if(connectionSlot != NULL && connectionSlot->getNetworkGameDataSynchCheckOkMap() == false) { label = label + " map"; + + string lastMapDataSynchError; + string lastMapTileDataSynchError; + string lastTechtreeDataSynchError; + + if(connectionSlot->getReceivedDataSynchCheck() == true && + lastMapDataSynchError != "map CRC mismatch") { + lastMapDataSynchError = "map CRC mismatch"; + ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); + serverInterface->sendTextMessage(lastMapDataSynchError,-1, true); + } } - if(connectionSlot->getNetworkGameDataSynchCheckOkTile() == false) - { + else { + lastMapDataSynchError = ""; + } + + connectionSlot= serverInterface->getSlot(i); + if(connectionSlot != NULL && connectionSlot->getNetworkGameDataSynchCheckOkTile() == false) { label = label + " tile"; + + if(connectionSlot->getReceivedDataSynchCheck() == true && + lastTileDataSynchError != "tileset CRC mismatch") { + lastTileDataSynchError = "tileset CRC mismatch"; + ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); + serverInterface->sendTextMessage(lastTileDataSynchError,-1,true); + } } - if(connectionSlot->getNetworkGameDataSynchCheckOkTech() == false) + else { + lastTileDataSynchError = ""; + } + + connectionSlot= serverInterface->getSlot(i); + if(connectionSlot != NULL && connectionSlot->getNetworkGameDataSynchCheckOkTech() == false) { label = label + " techtree"; + + if(connectionSlot->getReceivedDataSynchCheck() == true) { + ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); + string report = connectionSlot->getNetworkGameDataSynchCheckTechMismatchReport(); + + if(lastTechtreeDataSynchError != "techtree CRC mismatch" + report) { + lastTechtreeDataSynchError = "techtree CRC mismatch" + report; + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] report: %s\n",__FILE__,__FUNCTION__,__LINE__,report.c_str()); + + serverInterface->sendTextMessage("techtree CRC mismatch",-1,true); + vector reportLineTokens; + Tokenize(report,reportLineTokens,"\n"); + for(int reportLine = 0; reportLine < reportLineTokens.size(); ++reportLine) { + serverInterface->sendTextMessage(reportLineTokens[reportLine],-1,true); + } + } + } + } + else { + lastTechtreeDataSynchError = ""; + } + + connectionSlot= serverInterface->getSlot(i); + if(connectionSlot != NULL) { + connectionSlot->setReceivedDataSynchCheck(false); } } } diff --git a/source/glest_game/menu/menu_state_custom_game.h b/source/glest_game/menu/menu_state_custom_game.h index c1aa11b1a..bfe313a01 100644 --- a/source/glest_game/menu/menu_state_custom_game.h +++ b/source/glest_game/menu/menu_state_custom_game.h @@ -103,6 +103,10 @@ private: ChatManager chatManager; bool showFullConsole; + string lastMapDataSynchError; + string lastTileDataSynchError; + string lastTechtreeDataSynchError; + public: MenuStateCustomGame(Program *program, MainMenu *mainMenu ,bool openNetworkSlots= false, bool parentMenuIsMasterserver=false); ~MenuStateCustomGame(); diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index 96c912ca9..245f99ef2 100755 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -53,6 +53,8 @@ ClientInterface::ClientInterface(){ networkGameDataSynchCheckOkMap = false; networkGameDataSynchCheckOkTile = false; networkGameDataSynchCheckOkTech = false; + this->setNetworkGameDataSynchCheckTechMismatchReport(""); + this->setReceivedDataSynchCheck(false); } ClientInterface::~ClientInterface() @@ -147,8 +149,7 @@ std::string ClientInterface::getServerIpAddress() { return this->ip.getString(); } -void ClientInterface::updateLobby() -{ +void ClientInterface::updateLobby() { //clear chat variables clearChatInfo(); @@ -161,7 +162,6 @@ void ClientInterface::updateLobby() case nmtIntro: { NetworkMessageIntro networkMessageIntro; - if(receiveMessage(&networkMessageIntro)) { gotIntro = true; versionString = networkMessageIntro.getVersionString(); @@ -277,13 +277,19 @@ void ClientInterface::updateLobby() { NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData; - if(receiveMessage(&networkMessageSynchNetworkGameData)) - { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__); + if(receiveMessage(&networkMessageSynchNetworkGameData)) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got NetworkMessageSynchNetworkGameData, getTechCRCFileCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageSynchNetworkGameData.getTechCRCFileCount()); + + networkGameDataSynchCheckOkMap = false; + networkGameDataSynchCheckOkTile = false; + networkGameDataSynchCheckOkTech = false; + this->setNetworkGameDataSynchCheckTechMismatchReport(""); + this->setReceivedDataSynchCheck(false); int32 tilesetCRC = 0; int32 techCRC = 0; int32 mapCRC = 0; + vector > vctFileList; try { Config &config = Config::getInstance(); @@ -305,7 +311,7 @@ void ClientInterface::updateLobby() this->setNetworkGameDataSynchCheckOkTile((tilesetCRC == networkMessageSynchNetworkGameData.getTilesetCRC())); //if(this->getNetworkGameDataSynchCheckOkTile() == false) //{ - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] tilesetCRC info, local = %d, remote = %d, networkMessageSynchNetworkGameData.getTileset() = [%s]\n",__FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameData.getTilesetCRC(),networkMessageSynchNetworkGameData.getTileset().c_str()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] tilesetCRC info, local = %d, remote = %d, networkMessageSynchNetworkGameData.getTileset() = [%s]\n",__FILE__,__FUNCTION__,__LINE__,tilesetCRC,networkMessageSynchNetworkGameData.getTilesetCRC(),networkMessageSynchNetworkGameData.getTileset().c_str()); //} @@ -315,6 +321,17 @@ void ClientInterface::updateLobby() this->setNetworkGameDataSynchCheckOkTech((techCRC == networkMessageSynchNetworkGameData.getTechCRC())); + if(this->getNetworkGameDataSynchCheckOkTech() == false) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),string("/") + networkMessageSynchNetworkGameData.getTech() + "/*", ".xml", NULL); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + string report = networkMessageSynchNetworkGameData.getTechCRCFileMismatchReport(vctFileList); + this->setNetworkGameDataSynchCheckTechMismatchReport(report); + + } //if(this->getNetworkGameDataSynchCheckOkTech() == false) //{ SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] techCRC info, local = %d, remote = %d, networkMessageSynchNetworkGameData.getTech() = [%s]\n",__FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameData.getTechCRC(),networkMessageSynchNetworkGameData.getTech().c_str()); @@ -330,20 +347,21 @@ void ClientInterface::updateLobby() //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] file = [%s] checksum = %d\n",__FILE__,__FUNCTION__,file.c_str(),mapCRC); this->setNetworkGameDataSynchCheckOkMap((mapCRC == networkMessageSynchNetworkGameData.getMapCRC())); + this->setReceivedDataSynchCheck(true); //if(this->getNetworkGameDataSynchCheckOkMap() == false) //{ - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] mapCRC info, local = %d, remote = %d, file = [%s]\n",__FILE__,__FUNCTION__,mapCRC,networkMessageSynchNetworkGameData.getMapCRC(),file.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] mapCRC info, local = %d, remote = %d, file = [%s]\n",__FILE__,__FUNCTION__,__LINE__,mapCRC,networkMessageSynchNetworkGameData.getMapCRC(),file.c_str()); //} } catch(const runtime_error &ex) { string sErr = ex.what(); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] error during processing, sErr = [%s]\n",__FILE__,__FUNCTION__,sErr.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error during processing, sErr = [%s]\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str()); DisplayErrorMessage(sErr); } - NetworkMessageSynchNetworkGameDataStatus sendNetworkMessageSynchNetworkGameDataStatus(mapCRC,tilesetCRC,techCRC); + NetworkMessageSynchNetworkGameDataStatus sendNetworkMessageSynchNetworkGameDataStatus(mapCRC,tilesetCRC,techCRC,vctFileList); sendMessage(&sendNetworkMessageSynchNetworkGameDataStatus); } } @@ -411,28 +429,32 @@ void ClientInterface::updateLobby() { NetworkMessageLaunch networkMessageLaunch; - if(receiveMessage(&networkMessageLaunch)) - { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got NetworkMessageLaunch\n",__FILE__,__FUNCTION__); + if(receiveMessage(&networkMessageLaunch)) { + if(networkMessageLaunch.getMessageType() == nmtLaunch) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtLaunch\n",__FILE__,__FUNCTION__,__LINE__); + } + else { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); + } networkMessageLaunch.buildGameSettings(&gameSettings); //replace server player by network - for(int i= 0; isetNetworkGameDataSynchCheckTechMismatchReport(""); + this->setReceivedDataSynchCheck(false); + this->clearChatInfo(); } @@ -202,6 +205,7 @@ void ConnectionSlot::update(bool checkForNewClients) { if(networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false; if(networkGameDataSynchCheckOkTile) networkGameDataSynchCheckOkTile = false; if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false; + this->setReceivedDataSynchCheck(false); // Is the listener socket ready to be read? //if(serverInterface->getServerSocket()->isReadable() == true) @@ -235,10 +239,10 @@ void ConnectionSlot::update(bool checkForNewClients) { //send intro message when connected if(socket != NULL) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] accepted new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,serverInterface->getOpenSlotCount()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] accepted new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getOpenSlotCount()); if(hasOpenSlots == false) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] no open slots, disconnecting client\n",__FILE__,__FUNCTION__); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] !!!!!!!!WARNING - no open slots, disconnecting client\n",__FILE__,__FUNCTION__,__LINE__); if(socket != NULL) { NetworkMessageIntro networkMessageIntro(getNetworkVersionString(), getHostName(), playerIndex, nmgstNoSlots); @@ -248,7 +252,7 @@ void ConnectionSlot::update(bool checkForNewClients) { close(); } else { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] client will be assigned to the next open slot\n",__FILE__,__FUNCTION__); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] client will be assigned to the next open slot\n",__FILE__,__FUNCTION__,__LINE__); if(socket != NULL) { NetworkMessageIntro networkMessageIntro(getNetworkVersionString(), getHostName(), playerIndex, nmgstOk); @@ -393,9 +397,8 @@ void ConnectionSlot::update(bool checkForNewClients) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); gotIntro = true; - if(getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL) - { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] sending NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__); + if(getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sending NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__,__LINE__); NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(serverInterface->getGameSettings()); sendMessage(&networkMessageSynchNetworkGameData); @@ -407,13 +410,15 @@ void ConnectionSlot::update(bool checkForNewClients) { //process datasynch messages case nmtSynchNetworkGameDataStatus: { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtSynchNetworkGameDataStatus, gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro); if(gotIntro == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + NetworkMessageSynchNetworkGameDataStatus networkMessageSynchNetworkGameDataStatus; - if(receiveMessage(&networkMessageSynchNetworkGameDataStatus)) - { - receivedNetworkGameStatus = true; + if(receiveMessage(&networkMessageSynchNetworkGameDataStatus)) { + this->setNetworkGameDataSynchCheckTechMismatchReport(""); + this->setReceivedDataSynchCheck(false); Config &config = Config::getInstance(); string scenarioDir = ""; @@ -487,6 +492,9 @@ void ConnectionSlot::update(bool checkForNewClients) { //vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_techs) + "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList); vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList); } + + string report = networkMessageSynchNetworkGameDataStatus.getTechCRCFileMismatchReport(vctFileList); + this->setNetworkGameDataSynchCheckTechMismatchReport(report); } if(networkGameDataSynchCheckOkMap == false) { vctFileList.push_back(std::pair(Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir),mapCRC)); @@ -498,7 +506,26 @@ void ConnectionSlot::update(bool checkForNewClients) { sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck); //} } + else { + if(networkGameDataSynchCheckOkTech == false) { + //if(techCRC == 0) { + //vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_techs) + "/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList); + //vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList); + //} + //else { + //vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_techs) + "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList); + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL); + //} + + string report = networkMessageSynchNetworkGameDataStatus.getTechCRCFileMismatchReport(vctFileList); + this->setNetworkGameDataSynchCheckTechMismatchReport(report); + } + } } + + this->setReceivedDataSynchCheck(true); + receivedNetworkGameStatus = true; + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } } } diff --git a/source/glest_game/network/network_interface.h b/source/glest_game/network/network_interface.h index d900a5345..9ef08430c 100644 --- a/source/glest_game/network/network_interface.h +++ b/source/glest_game/network/network_interface.h @@ -84,6 +84,8 @@ protected: bool networkGameDataSynchCheckOkMap; bool networkGameDataSynchCheckOkTile; bool networkGameDataSynchCheckOkTech; + string networkGameDataSynchCheckTechMismatchReport; + bool receivedDataSynchCheck; std::vector chatTextList; NetworkMessagePing lastPingInfo; @@ -146,6 +148,12 @@ public: std::string getIpAddress(); float getThreadedPingMS(std::string host); + + string getNetworkGameDataSynchCheckTechMismatchReport() const {return networkGameDataSynchCheckTechMismatchReport;} + void setNetworkGameDataSynchCheckTechMismatchReport(string value) {networkGameDataSynchCheckTechMismatchReport = value;} + + bool getReceivedDataSynchCheck() const {return receivedDataSynchCheck;} + void setReceivedDataSynchCheck(bool value) { receivedDataSynchCheck = value; } }; // ===================================================== diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index b16e128c0..35985574b 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -24,10 +24,12 @@ #include "map.h" #include "platform_util.h" #include "config.h" +#include using namespace Shared::Platform; using namespace Shared::Util; using namespace std; +using std::min; namespace Glest{ namespace Game{ @@ -277,7 +279,12 @@ bool NetworkMessageLaunch::receive(Socket* socket){ } void NetworkMessageLaunch::send(Socket* socket) const{ - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtLaunch\n",__FILE__,__FUNCTION__,__LINE__); + if(data.messageType == nmtLaunch) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtLaunch\n",__FILE__,__FUNCTION__,__LINE__); + } + else { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d\n",__FILE__,__FUNCTION__,__LINE__,data.messageType); + } NetworkMessage::send(socket, &data, sizeof(data)); } @@ -438,11 +445,14 @@ void NetworkMessageQuit::send(Socket* socket) const{ NetworkMessageSynchNetworkGameData::NetworkMessageSynchNetworkGameData(const GameSettings *gameSettings) { - data.messageType= nmtSynchNetworkGameData; + data.header.messageType= nmtSynchNetworkGameData; - data.map = gameSettings->getMap(); - data.tileset = gameSettings->getTileset(); - data.tech = gameSettings->getTech(); + if(gameSettings == NULL) { + throw std::runtime_error("gameSettings == NULL"); + } + data.header.map = gameSettings->getMap(); + data.header.tileset = gameSettings->getTileset(); + data.header.tech = gameSettings->getTech(); Config &config = Config::getInstance(); string scenarioDir = ""; @@ -457,68 +467,303 @@ NetworkMessageSynchNetworkGameData::NetworkMessageSynchNetworkGameData(const Gam } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //Checksum checksum; - //data.tilesetCRC = getFolderTreeContentsCheckSumRecursively(string(GameConstants::folder_path_tilesets) + "/" + gameSettings->getTileset() + "/*", "xml", NULL); - data.tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + gameSettings->getTileset() + string("/*"), ".xml", NULL); - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] data.tilesetCRC = %d, [%s]\n",__FILE__,__FUNCTION__,__LINE__, data.tilesetCRC,gameSettings->getTileset().c_str()); + data.header.tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + gameSettings->getTileset() + string("/*"), ".xml", NULL); + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] data.tilesetCRC = %d, [%s]\n",__FILE__,__FUNCTION__,__LINE__, data.header.tilesetCRC,gameSettings->getTileset().c_str()); //tech, load before map because of resources - //data.techCRC = getFolderTreeContentsCheckSumRecursively(string(GameConstants::folder_path_techs) + "/" + gameSettings->getTech() + "/*", "xml", NULL); - data.techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,scenarioDir), string("/") + gameSettings->getTech() + string("/*"), ".xml", NULL); + data.header.techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,scenarioDir), string("/") + gameSettings->getTech() + string("/*"), ".xml", NULL); - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] data.techCRC = %d, [%s]\n",__FILE__,__FUNCTION__,__LINE__, data.techCRC,gameSettings->getTech().c_str()); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] data.techCRC = %d, [%s]\n",__FILE__,__FUNCTION__,__LINE__, data.header.techCRC,gameSettings->getTech().c_str()); + + vector > vctFileList; + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),string("/") + gameSettings->getTech() + string("/*"), ".xml",&vctFileList); + data.header.techCRCFileCount = min((int)vctFileList.size(),(int)maxFileCRCCount); + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctFileList.size() = %d, maxFileCRCCount = %d\n",__FILE__,__FUNCTION__,__LINE__, vctFileList.size(),maxFileCRCCount); + + for(int idx =0; idx < data.header.techCRCFileCount; ++idx) { + const std::pair &fileInfo = vctFileList[idx]; + data.detail.techCRCFileList[idx] = fileInfo.first; + data.detail.techCRCFileCRCList[idx] = fileInfo.second; + } //map Checksum checksum; string file = Map::getMapPath(gameSettings->getMap(),scenarioDir); checksum.addFile(file); - data.mapCRC = checksum.getSum(); - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] file = [%s] checksum = %d\n",__FILE__,__FUNCTION__,file.c_str(),data.mapCRC); - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] data.mapCRC = %d, [%s]\n",__FILE__,__FUNCTION__,__LINE__, data.mapCRC,gameSettings->getMap().c_str()); + data.header.mapCRC = checksum.getSum(); + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] data.mapCRC = %d, [%s]\n",__FILE__,__FUNCTION__,__LINE__, data.header.mapCRC,gameSettings->getMap().c_str()); } -bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) { - bool result = NetworkMessage::receive(socket, &data, sizeof(data)); +string NetworkMessageSynchNetworkGameData::getTechCRCFileMismatchReport(vector > &vctFileList) { + string result = "Filecount local: " + intToStr(vctFileList.size()) + " remote: " + intToStr(data.header.techCRCFileCount) + "\n"; + for(int idx = 0; idx < vctFileList.size(); ++idx) { + std::pair &fileInfo = vctFileList[idx]; + bool fileFound = false; + int32 remoteCRC = -1; + for(int j = 0; j < data.header.techCRCFileCount; ++j) { + string networkFile = data.detail.techCRCFileList[j].getString(); + int32 &networkFileCRC = data.detail.techCRCFileCRCList[j]; + if(fileInfo.first == networkFile) { + fileFound = true; + remoteCRC = networkFileCRC; + break; + } + } - data.map.nullTerminate(); - data.tileset.nullTerminate(); - data.tech.nullTerminate(); + if(fileFound == false) { + result = result + "local file [" + fileInfo.first + "] missing remotely.\n"; + } + else if(fileInfo.second != remoteCRC) { + result = result + "local file [" + fileInfo.first + "] CRC mismatch.\n"; + } + } + + for(int i = 0; i < data.header.techCRCFileCount; ++i) { + string networkFile = data.detail.techCRCFileList[i].getString(); + int32 &networkFileCRC = data.detail.techCRCFileCRCList[i]; + bool fileFound = false; + int32 localCRC = -1; + for(int idx = 0; idx < vctFileList.size(); ++idx) { + std::pair &fileInfo = vctFileList[idx]; + if(networkFile == fileInfo.first) { + fileFound = true; + localCRC = fileInfo.second; + break; + } + } + + if(fileFound == false) { + result = result + "remote file [" + networkFile + "] missing locally.\n"; + } + else if(networkFileCRC != localCRC) { + result = result + "remote file [" + networkFile + "] CRC mismatch.\n"; + } + } return result; } -void NetworkMessageSynchNetworkGameData::send(Socket* socket) const { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtSynchNetworkGameData\n",__FILE__,__FUNCTION__,__LINE__); +bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to get nmtSynchNetworkGameData\n",__FILE__,__FUNCTION__,__LINE__); - assert(data.messageType==nmtSynchNetworkGameData); - NetworkMessage::send(socket, &data, sizeof(data)); + data.header.techCRCFileCount = 0; + + for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); + + if (NetworkMessage::peek(socket, &data, HeaderSize) == true) { + break; + } + else { + sleep(1); // sleep 1 ms to wait for socket data + } + } + + if (NetworkMessage::peek(socket, &data, HeaderSize) == false) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR / WARNING!!! NetworkMessage::peek failed!\n",__FILE__,__FUNCTION__,__LINE__); + return false; + } + + data.header.map.nullTerminate(); + data.header.tileset.nullTerminate(); + data.header.tech.nullTerminate(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, data.techCRCFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.techCRCFileCount); + + bool result = NetworkMessage::receive(socket, &data, HeaderSize); + if(result == true && data.header.techCRCFileCount > 0) { + for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); + + if (NetworkMessage::peek(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)) == true) { + break; + } + else { + sleep(1); // sleep 1 ms to wait for socket data + } + } + + result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)); + if(result == true) { + for(int i = 0; i < data.header.techCRCFileCount; ++i) { + data.detail.techCRCFileList[i].nullTerminate(); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] data.detail.techCRCFileList[i] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,data.detail.techCRCFileList[i].getString().c_str()); + } + + for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); + if (NetworkMessage::peek(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)) == true) { + break; + } + else { + sleep(1); // sleep 1 ms to wait for socket data + } + } + + result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)); + } + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result); + return result; } +void NetworkMessageSynchNetworkGameData::send(Socket* socket) const { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to send nmtSynchNetworkGameData\n",__FILE__,__FUNCTION__,__LINE__); + + assert(data.messageType==nmtSynchNetworkGameData); + NetworkMessage::send(socket, &data, HeaderSize); + if(data.header.techCRCFileCount > 0) { + NetworkMessage::send(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)); + NetworkMessage::send(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)); + } +} // ===================================================== // class NetworkMessageSynchNetworkGameDataStatus // ===================================================== -NetworkMessageSynchNetworkGameDataStatus::NetworkMessageSynchNetworkGameDataStatus(int32 mapCRC, int32 tilesetCRC, int32 techCRC) +NetworkMessageSynchNetworkGameDataStatus::NetworkMessageSynchNetworkGameDataStatus(int32 mapCRC, int32 tilesetCRC, int32 techCRC, vector > &vctFileList) { - data.messageType= nmtSynchNetworkGameDataStatus; + data.header.messageType= nmtSynchNetworkGameDataStatus; - data.tilesetCRC = tilesetCRC; - data.techCRC = techCRC; - data.mapCRC = mapCRC; + data.header.tilesetCRC = tilesetCRC; + data.header.techCRC = techCRC; + data.header.mapCRC = mapCRC; + + data.header.techCRCFileCount = min((int)vctFileList.size(),(int)maxFileCRCCount); + for(int idx =0; idx < data.header.techCRCFileCount; ++idx) { + const std::pair &fileInfo = vctFileList[idx]; + data.detail.techCRCFileList[idx] = fileInfo.first; + data.detail.techCRCFileCRCList[idx] = fileInfo.second; + } } -bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) -{ - return NetworkMessage::receive(socket, &data, sizeof(data)); +string NetworkMessageSynchNetworkGameDataStatus::getTechCRCFileMismatchReport(vector > &vctFileList) { + string result = "Filecount local: " + intToStr(vctFileList.size()) + " remote: " + intToStr(data.header.techCRCFileCount) + "\n"; + for(int idx = 0; idx < vctFileList.size(); ++idx) { + std::pair &fileInfo = vctFileList[idx]; + bool fileFound = false; + int32 remoteCRC = -1; + for(int j = 0; j < data.header.techCRCFileCount; ++j) { + string networkFile = data.detail.techCRCFileList[j].getString(); + int32 &networkFileCRC = data.detail.techCRCFileCRCList[j]; + if(fileInfo.first == networkFile) { + fileFound = true; + remoteCRC = networkFileCRC; + break; + } + } + + if(fileFound == false) { + result = result + "local file [" + fileInfo.first + "] missing remotely.\n"; + } + else if(fileInfo.second != remoteCRC) { + result = result + "local file [" + fileInfo.first + "] CRC mismatch.\n"; + } + } + + for(int i = 0; i < data.header.techCRCFileCount; ++i) { + string networkFile = data.detail.techCRCFileList[i].getString(); + int32 &networkFileCRC = data.detail.techCRCFileCRCList[i]; + bool fileFound = false; + int32 localCRC = -1; + for(int idx = 0; idx < vctFileList.size(); ++idx) { + std::pair &fileInfo = vctFileList[idx]; + + if(networkFile == fileInfo.first) { + fileFound = true; + localCRC = fileInfo.second; + break; + } + } + + if(fileFound == false) { + result = result + "remote file [" + networkFile + "] missing locally.\n"; + } + else if(networkFileCRC != localCRC) { + result = result + "remote file [" + networkFile + "] CRC mismatch.\n"; + } + } + + return result; +} + +bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to get nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__,__LINE__); + data.header.techCRCFileCount = 0; + + for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); + if (NetworkMessage::peek(socket, &data, HeaderSize) == true) { + break; + } + else { + sleep(1); // sleep 1 ms to wait for socket data + } + } + + if (NetworkMessage::peek(socket, &data, HeaderSize) == false) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR / WARNING!!! NetworkMessage::peek failed!\n",__FILE__,__FUNCTION__,__LINE__); + return false; + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, data.techCRCFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.techCRCFileCount); + + bool result = NetworkMessage::receive(socket, &data, HeaderSize); + if(result == true && data.header.techCRCFileCount > 0) { + for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); + + if (NetworkMessage::peek(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)) == true) { + break; + } + else { + sleep(1); // sleep 1 ms to wait for socket data + } + } + + result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)); + if(result == true) { + for(int i = 0; i < data.header.techCRCFileCount; ++i) { + data.detail.techCRCFileList[i].nullTerminate(); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] data.detail.techCRCFileList[i] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,data.detail.techCRCFileList[i].getString().c_str()); + } + + for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); + + if (NetworkMessage::peek(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)) == true) { + break; + } + else { + sleep(1); // sleep 1 ms to wait for socket data + } + } + + result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)); + } + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result); + + return result; } void NetworkMessageSynchNetworkGameDataStatus::send(Socket* socket) const { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__,__LINE__); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to send nmtSynchNetworkGameDataStatus, data.header.techCRCFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.techCRCFileCount); assert(data.messageType==nmtSynchNetworkGameDataStatus); - NetworkMessage::send(socket, &data, sizeof(data)); + //int totalMsgSize = HeaderSize + (sizeof(DataDetail) * data.header.techCRCFileCount); + NetworkMessage::send(socket, &data, HeaderSize); + if(data.header.techCRCFileCount > 0) { + NetworkMessage::send(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)); + NetworkMessage::send(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)); + } } // ===================================================== diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index d698f15c4..11ce45f54 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -179,16 +179,17 @@ public: class NetworkMessageLaunch: public NetworkMessage{ private: static const int maxStringSize= 256; + static const int maxSmallStringSize= 60; private: struct Data{ int8 messageType; NetworkString description; - NetworkString map; - NetworkString tileset; - NetworkString tech; - NetworkString factionTypeNames[GameConstants::maxPlayers]; //faction names - NetworkString networkPlayerNames[GameConstants::maxPlayers]; //networkPlayerNames + NetworkString map; + NetworkString tileset; + NetworkString tech; + NetworkString factionTypeNames[GameConstants::maxPlayers]; //faction names + NetworkString networkPlayerNames[GameConstants::maxPlayers]; //networkPlayerNames int8 factionControls[GameConstants::maxPlayers]; @@ -205,7 +206,6 @@ private: uint8 networkFramePeriod; // allowed values 0 - 255 int8 networkPauseGameForLaggedClients; int8 pathFinderType; - }; private: @@ -216,6 +216,7 @@ public: NetworkMessageLaunch(const GameSettings *gameSettings,int8 messageType); void buildGameSettings(GameSettings *gameSettings) const; + int getMessageType() const { return data.messageType; } virtual bool receive(Socket* socket); virtual void send(Socket* socket) const; @@ -341,10 +342,12 @@ class NetworkMessageSynchNetworkGameData: public NetworkMessage{ private: -static const int maxStringSize= 256; +static const int maxStringSize= 100; +static const int maxFileCRCCount= 500; private: - struct Data{ + + struct DataHeader { int8 messageType; NetworkString map; @@ -354,6 +357,23 @@ private: int32 mapCRC; int32 tilesetCRC; int32 techCRC; + + int32 techCRCFileCount; + }; + + static const int32 HeaderSize = sizeof(DataHeader); + + struct DataDetail { + NetworkString techCRCFileList[maxFileCRCCount]; + int32 techCRCFileCRCList[maxFileCRCCount]; + }; + + static const int32 DetailSize1 = sizeof(NetworkString); + static const int32 DetailSize2 = sizeof(int32); + + struct Data { + DataHeader header; + DataDetail detail; }; private: @@ -366,13 +386,19 @@ public: virtual bool receive(Socket* socket); virtual void send(Socket* socket) const; - string getMap() const {return data.map.getString();} - string getTileset() const {return data.tileset.getString();} - string getTech() const {return data.tech.getString();} + string getMap() const {return data.header.map.getString();} + string getTileset() const {return data.header.tileset.getString();} + string getTech() const {return data.header.tech.getString();} - int32 getMapCRC() const {return data.mapCRC;} - int32 getTilesetCRC() const {return data.tilesetCRC;} - int32 getTechCRC() const {return data.techCRC;} + int32 getMapCRC() const {return data.header.mapCRC;} + int32 getTilesetCRC() const {return data.header.tilesetCRC;} + int32 getTechCRC() const {return data.header.techCRC;} + + int32 getTechCRCFileCount() const {return data.header.techCRCFileCount;} + const NetworkString * getTechCRCFileList() const {return &data.detail.techCRCFileList[0];} + const int32 * getTechCRCFileCRCList() const {return data.detail.techCRCFileCRCList;} + + string getTechCRCFileMismatchReport(vector > &vctFileList); }; #pragma pack(pop) @@ -387,16 +413,33 @@ class NetworkMessageSynchNetworkGameDataStatus: public NetworkMessage{ private: -static const int maxStringSize= 256; +static const int maxStringSize= 100; +static const int maxFileCRCCount= 500; private: - struct Data{ + + struct DataHeader { int8 messageType; int32 mapCRC; int32 tilesetCRC; int32 techCRC; + int32 techCRCFileCount; + }; + static const int32 HeaderSize = sizeof(DataHeader); + + struct DataDetail { + NetworkString techCRCFileList[maxFileCRCCount]; + int32 techCRCFileCRCList[maxFileCRCCount]; + }; + + static const int32 DetailSize1 = sizeof(NetworkString); + static const int32 DetailSize2 = sizeof(int32); + + struct Data { + DataHeader header; + DataDetail detail; }; private: @@ -404,14 +447,21 @@ private: public: NetworkMessageSynchNetworkGameDataStatus() {}; - NetworkMessageSynchNetworkGameDataStatus(int32 mapCRC, int32 tilesetCRC, int32 techCRC); + NetworkMessageSynchNetworkGameDataStatus(int32 mapCRC, int32 tilesetCRC, int32 techCRC, vector > &vctFileList); virtual bool receive(Socket* socket); virtual void send(Socket* socket) const; - int32 getMapCRC() const {return data.mapCRC;} - int32 getTilesetCRC() const {return data.tilesetCRC;} - int32 getTechCRC() const {return data.techCRC;} + int32 getMapCRC() const {return data.header.mapCRC;} + int32 getTilesetCRC() const {return data.header.tilesetCRC;} + int32 getTechCRC() const {return data.header.techCRC;} + + int32 getTechCRCFileCount() const {return data.header.techCRCFileCount;} + const NetworkString * getTechCRCFileList() const {return &data.detail.techCRCFileList[0];} + const int32 * getTechCRCFileCRCList() const {return data.detail.techCRCFileCRCList;} + + string getTechCRCFileMismatchReport(vector > &vctFileList); + }; #pragma pack(pop) diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 4250296e3..63b35c625 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -997,7 +997,7 @@ bool ServerInterface::launchGame(const GameSettings* gameSettings){ bool bOkToStart = true; - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); for(int i= 0; i > getFolderTreeContentsCheckSumListRecursively(ve SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders found CACHED result for cacheKey [%s]\n",__FILE__,__FUNCTION__,cacheKey.c_str()); return crcTreeCache[cacheKey]; } + else { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders, NO CACHE found result for cacheKey [%s]\n",__FILE__,__FUNCTION__,cacheKey.c_str()); + } + + bool topLevelCaller = (recursiveMap == NULL); vector > checksumFiles = (recursiveMap == NULL ? vector >() : *recursiveMap); for(size_t idx = 0; idx < count; ++idx) { string path = paths[idx] + pathSearchString; - getFolderTreeContentsCheckSumListRecursively(path, filterFileExt, &checksumFiles); + checksumFiles = getFolderTreeContentsCheckSumListRecursively(path, filterFileExt, &checksumFiles); } - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size()); + + if(topLevelCaller == true) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION, checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size()); + } crcTreeCache[cacheKey] = checksumFiles; return crcTreeCache[cacheKey]; @@ -498,6 +507,7 @@ vector > getFolderTreeContentsCheckSumListRecursively(co return crcTreeCache[cacheKey]; } + bool topLevelCaller = (recursiveMap == NULL); vector > checksumFiles = (recursiveMap == NULL ? vector >() : *recursiveMap); //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str()); @@ -562,7 +572,11 @@ vector > getFolderTreeContentsCheckSumListRecursively(co crcTreeCache[cacheKey] = checksumFiles; - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] cacheKey [%s]\n",__FILE__,__FUNCTION__,path.c_str(),cacheKey.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] cacheKey [%s] checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,path.c_str(),cacheKey.c_str(),checksumFiles.size()); + + if(topLevelCaller == true) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION, checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size()); + } return crcTreeCache[cacheKey]; }