diff --git a/source/glest_game/game/game_constants.h b/source/glest_game/game/game_constants.h index 85e52c139..1726c7dfc 100644 --- a/source/glest_game/game/game_constants.h +++ b/source/glest_game/game/game_constants.h @@ -46,6 +46,8 @@ public: static const char *folder_path_techs; static const char *folder_path_tilesets; static const char *folder_path_tutorials; + + static const char *NETWORK_SLOT_UNCONNECTED_SLOTNAME; }; enum PathType { diff --git a/source/glest_game/global/config.cpp b/source/glest_game/global/config.cpp index 08a1c061f..33bf3e435 100644 --- a/source/glest_game/global/config.cpp +++ b/source/glest_game/global/config.cpp @@ -37,6 +37,7 @@ const char *GameConstants::folder_path_techs = "techs"; const char *GameConstants::folder_path_tilesets = "tilesets"; const char *GameConstants::folder_path_tutorials = "tutorials"; +const char *GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME = "???"; // ===================================================== // class Config diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 0fb979fe9..11b781238 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -154,6 +154,7 @@ const Vec4f Renderer::defDiffuseColor= Vec4f(1.f, 1.f, 1.f, 1.f); const Vec4f Renderer::defAmbientColor= Vec4f(1.f * ambFactor, 1.f * ambFactor, 1.f * ambFactor, 1.f); const Vec4f Renderer::defColor= Vec4f(1.f, 1.f, 1.f, 1.f); +//const float Renderer::maxLightDist= 100.f; const float Renderer::maxLightDist= 1000.f; // ==================== constructor and destructor ==================== @@ -666,9 +667,11 @@ void Renderer::renderMouse3d() { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color.ptr()); const Model *buildingModel= building->getFirstStOfClass(scStop)->getAnimation(); - float rotateAmount = gui->getSelectedFacing() * 90.f; - if(rotateAmount > 0) { - glRotatef(rotateAmount, 0.f, 1.f, 0.f); + if(gui->getSelectedFacing() != CardinalDir::NORTH) { + float rotateAmount = gui->getSelectedFacing() * 90.f; + if(rotateAmount > 0) { + glRotatef(rotateAmount, 0.f, 1.f, 0.f); + } } buildingModel->updateInterpolationData(0.f, false); diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 8920d46a0..f05e8f8cc 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -235,7 +235,8 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ break; } } - if((listBoxControls[i].getSelectedItemIndex()==ctNetwork) && (labelNetStatus[i].getText()=="???")){ + if((listBoxControls[i].getSelectedItemIndex() == ctNetwork) && + (labelNetStatus[i].getText() == GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME)) { if(grabSlotButton[i].mouseClick(x, y) ) { soundRenderer.playFx(coreData.getClickSoundA()); @@ -354,7 +355,8 @@ void MenuStateConnectedGame::render(){ renderer.renderListBox(&listBoxTeams[i]); //renderer.renderLabel(&labelNetStatus[i]); - if((listBoxControls[i].getSelectedItemIndex()==ctNetwork) && (labelNetStatus[i].getText()=="???")){ + if((listBoxControls[i].getSelectedItemIndex() == ctNetwork) && + (labelNetStatus[i].getText() == GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME)) { renderer.renderButton(&grabSlotButton[i]); } else if((listBoxControls[i].getSelectedItemIndex()==ctNetwork) || diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index 3169d78ca..a4f7ec81c 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -1167,7 +1167,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) { gameSettings->setNetworkPlayerName(slotIndex, connectionSlot->getName()); } else { - gameSettings->setNetworkPlayerName(slotIndex, "Network"); + gameSettings->setNetworkPlayerName(slotIndex, GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME); } } else if (listBoxControls[i].getSelectedItemIndex() == ctHuman) { diff --git a/source/glest_game/menu/menu_state_masterserver.cpp b/source/glest_game/menu/menu_state_masterserver.cpp index d781ef324..2abab5907 100644 --- a/source/glest_game/menu/menu_state_masterserver.cpp +++ b/source/glest_game/menu/menu_state_masterserver.cpp @@ -273,6 +273,9 @@ void MenuStateMasterserver::mouseClick(int x, int y, MouseButton mouseButton){ soundRenderer.playFx(coreData.getClickSoundB()); needUpdateFromServer = false; safeMutex.ReleaseLock(); + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //BaseThread::shutdownAndWait(updateFromMasterserverThread); delete updateFromMasterserverThread; updateFromMasterserverThread = NULL; diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index 983523b06..9b870aa4e 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -211,14 +211,18 @@ void ConnectionSlot::update(bool checkForNewClients) { // Is the listener socket ready to be read? //if(serverInterface->getServerSocket()->isReadable() == true) if(checkForNewClients == true) { - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] BEFORE accept new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,serverInterface->getOpenSlotCount()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] BEFORE accept new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,serverInterface->getOpenSlotCount()); bool hasOpenSlots = (serverInterface->getOpenSlotCount() > 0); if(serverInterface->getServerSocket()->hasDataToRead() == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); socket = serverInterface->getServerSocket()->accept(); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); if(socket != NULL) { serverInterface->updateListen(); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); } } + //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()); @@ -253,247 +257,249 @@ void ConnectionSlot::update(bool checkForNewClients) { chatSender.clear(); chatTeamIndex= -1; - NetworkMessageType networkMessageType= getNextMessageType(); + if(socket->hasDataToRead() == true) { + NetworkMessageType networkMessageType= getNextMessageType(); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] networkMessageType = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageType); - //process incoming commands - switch(networkMessageType) { + //process incoming commands + switch(networkMessageType) { - case nmtInvalid: - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtInvalid\n",__FILE__,__FUNCTION__,__LINE__); - break; + case nmtInvalid: + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtInvalid\n",__FILE__,__FUNCTION__,__LINE__); + break; - case nmtText: - { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtText\n",__FILE__,__FUNCTION__); + case nmtText: + { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtText\n",__FILE__,__FUNCTION__); - NetworkMessageText networkMessageText; - if(receiveMessage(&networkMessageText)) { - chatText = networkMessageText.getText(); - chatSender = networkMessageText.getSender(); - chatTeamIndex = networkMessageText.getTeamIndex(); + NetworkMessageText networkMessageText; + if(receiveMessage(&networkMessageText)) { + chatText = networkMessageText.getText(); + chatSender = networkMessageText.getSender(); + chatTeamIndex = networkMessageText.getTeamIndex(); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] chatText [%s] chatSender [%s] chatTeamIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,chatText.c_str(),chatSender.c_str(),chatTeamIndex); - } - } - break; - - //command list - case nmtCommandList: { - - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtCommandList\n",__FILE__,__FUNCTION__); - - //throw runtime_error("test"); - - NetworkMessageCommandList networkMessageCommandList; - if(receiveMessage(&networkMessageCommandList)) { - currentFrameCount = networkMessageCommandList.getFrameCount(); - lastReceiveCommandListTime = time(NULL); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount); - - for(int i= 0; irequestCommand(networkMessageCommandList.getCommand(i)); - vctPendingNetworkCommandList.push_back(*networkMessageCommandList.getCommand(i)); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] chatText [%s] chatSender [%s] chatTeamIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,chatText.c_str(),chatSender.c_str(),chatTeamIndex); } } - } - break; + break; - //process intro messages - case nmtIntro: - { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtIntro\n",__FILE__,__FUNCTION__); + //command list + case nmtCommandList: { - NetworkMessageIntro networkMessageIntro; - if(receiveMessage(&networkMessageIntro)) + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtCommandList\n",__FILE__,__FUNCTION__); + + //throw runtime_error("test"); + + NetworkMessageCommandList networkMessageCommandList; + if(receiveMessage(&networkMessageCommandList)) { + currentFrameCount = networkMessageCommandList.getFrameCount(); + lastReceiveCommandListTime = time(NULL); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount); + + for(int i= 0; irequestCommand(networkMessageCommandList.getCommand(i)); + vctPendingNetworkCommandList.push_back(*networkMessageCommandList.getCommand(i)); + } + } + } + break; + + //process intro messages + case nmtIntro: { - gotIntro = true; - name= networkMessageIntro.getName(); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtIntro\n",__FILE__,__FUNCTION__); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got name [%s]\n",__FILE__,__FUNCTION__,name.c_str()); - - if(getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL) + NetworkMessageIntro networkMessageIntro; + if(receiveMessage(&networkMessageIntro)) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] sending NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__); + gotIntro = true; + name= networkMessageIntro.getName(); - NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(serverInterface->getGameSettings()); - sendMessage(&networkMessageSynchNetworkGameData); - } - } - } - break; + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got name [%s]\n",__FILE__,__FUNCTION__,name.c_str()); - //process datasynch messages - case nmtSynchNetworkGameDataStatus: - { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__); + if(getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL) + { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] sending NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__); - NetworkMessageSynchNetworkGameDataStatus networkMessageSynchNetworkGameDataStatus; - if(receiveMessage(&networkMessageSynchNetworkGameDataStatus)) - { - receivedNetworkGameStatus = true; - - Config &config = Config::getInstance(); - string scenarioDir = ""; - if(serverInterface->getGameSettings()->getScenarioDir() != "") { - scenarioDir = serverInterface->getGameSettings()->getScenarioDir(); - if(EndsWith(scenarioDir, ".xml") == true) { - scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); - scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1); - } - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str()); - } - - //tileset - int32 tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), ".xml", NULL); - int32 techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,scenarioDir), "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL); - Checksum checksum; - string file = Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir); - checksum.addFile(file); - int32 mapCRC = checksum.getSum(); - - networkGameDataSynchCheckOkMap = (networkMessageSynchNetworkGameDataStatus.getMapCRC() == mapCRC); - networkGameDataSynchCheckOkTile = (networkMessageSynchNetworkGameDataStatus.getTilesetCRC() == tilesetCRC); - networkGameDataSynchCheckOkTech = (networkMessageSynchNetworkGameDataStatus.getTechCRC() == techCRC); - - // For testing - //techCRC++; - - if( networkGameDataSynchCheckOkMap == true && - networkGameDataSynchCheckOkTile == true && - networkGameDataSynchCheckOkTech == true) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] client data synch ok\n",__FILE__,__FUNCTION__); - } - else { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] mapCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,mapCRC,networkMessageSynchNetworkGameDataStatus.getMapCRC()); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] tilesetCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameDataStatus.getTilesetCRC()); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] techCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameDataStatus.getTechCRC()); - - if(allowDownloadDataSynch == true) { - // Now get all filenames with their CRC values and send to the client - vctFileList.clear(); - - Config &config = Config::getInstance(); - string scenarioDir = ""; - if(serverInterface->getGameSettings()->getScenarioDir() != "") { - scenarioDir = serverInterface->getGameSettings()->getScenarioDir(); - if(EndsWith(scenarioDir, ".xml") == true) { - scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); - scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1); - } - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str()); - } - - if(networkGameDataSynchCheckOkTile == false) { - if(tilesetCRC == 0) { - //vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_tilesets) + "/" + serverInterface->getGameSettings()->getTileset() + "/*", "", &vctFileList); - vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), "", &vctFileList); - } - else { - //vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_tilesets) + "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList); - vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList); - } - } - 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", &vctFileList); - } - } - if(networkGameDataSynchCheckOkMap == false) { - vctFileList.push_back(std::pair(Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir),mapCRC)); - } - - //for(int i = 0; i < vctFileList.size(); i++) - //{ - NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), 1, vctFileList[0].second, vctFileList[0].first); - sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck); - //} + NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(serverInterface->getGameSettings()); + sendMessage(&networkMessageSynchNetworkGameData); } } } - } - break; + break; - case nmtSynchNetworkGameDataFileCRCCheck: - { - - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck\n",__FILE__,__FUNCTION__); - - NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck; - if(receiveMessage(&networkMessageSynchNetworkGameDataFileCRCCheck)) + //process datasynch messages + case nmtSynchNetworkGameDataStatus: { - int fileIndex = networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex(); - NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), fileIndex, vctFileList[fileIndex-1].second, vctFileList[fileIndex-1].first); - sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck); - } - } - break; + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__); - case nmtSynchNetworkGameDataFileGet: - { + NetworkMessageSynchNetworkGameDataStatus networkMessageSynchNetworkGameDataStatus; + if(receiveMessage(&networkMessageSynchNetworkGameDataStatus)) + { + receivedNetworkGameStatus = true; - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileGet\n",__FILE__,__FUNCTION__); + Config &config = Config::getInstance(); + string scenarioDir = ""; + if(serverInterface->getGameSettings()->getScenarioDir() != "") { + scenarioDir = serverInterface->getGameSettings()->getScenarioDir(); + if(EndsWith(scenarioDir, ".xml") == true) { + scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); + scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1); + } - NetworkMessageSynchNetworkGameDataFileGet networkMessageSynchNetworkGameDataFileGet; - if(receiveMessage(&networkMessageSynchNetworkGameDataFileGet)) { - FileTransferInfo fileInfo; - fileInfo.hostType = eServer; - //fileInfo.serverIP = this->ip.getString(); - fileInfo.serverPort = Config::getInstance().getInt("ServerPort",intToStr(GameConstants::serverPort).c_str()); - fileInfo.fileName = networkMessageSynchNetworkGameDataFileGet.getFileName(); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str()); + } - FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo); - fileXferThread->start(); - } - } - break; + //tileset + int32 tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), ".xml", NULL); + int32 techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,scenarioDir), "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL); + Checksum checksum; + string file = Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir); + checksum.addFile(file); + int32 mapCRC = checksum.getSum(); - case nmtSwitchSetupRequest: - { - SwitchSetupRequest switchSetupRequest; - if(receiveMessage(&switchSetupRequest)) { - Mutex *mutex = getServerSynchAccessor(); - if(mutex != NULL) mutex->p(); + networkGameDataSynchCheckOkMap = (networkMessageSynchNetworkGameDataStatus.getMapCRC() == mapCRC); + networkGameDataSynchCheckOkTile = (networkMessageSynchNetworkGameDataStatus.getTilesetCRC() == tilesetCRC); + networkGameDataSynchCheckOkTech = (networkMessageSynchNetworkGameDataStatus.getTechCRC() == techCRC); - if(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]==NULL) { - serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]= new SwitchSetupRequest(); + // For testing + //techCRC++; + + if( networkGameDataSynchCheckOkMap == true && + networkGameDataSynchCheckOkTile == true && + networkGameDataSynchCheckOkTech == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] client data synch ok\n",__FILE__,__FUNCTION__); + } + else { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] mapCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,mapCRC,networkMessageSynchNetworkGameDataStatus.getMapCRC()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] tilesetCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameDataStatus.getTilesetCRC()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] techCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameDataStatus.getTechCRC()); + + if(allowDownloadDataSynch == true) { + // Now get all filenames with their CRC values and send to the client + vctFileList.clear(); + + Config &config = Config::getInstance(); + string scenarioDir = ""; + if(serverInterface->getGameSettings()->getScenarioDir() != "") { + scenarioDir = serverInterface->getGameSettings()->getScenarioDir(); + if(EndsWith(scenarioDir, ".xml") == true) { + scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); + scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1); + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str()); + } + + if(networkGameDataSynchCheckOkTile == false) { + if(tilesetCRC == 0) { + //vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_tilesets) + "/" + serverInterface->getGameSettings()->getTileset() + "/*", "", &vctFileList); + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), "", &vctFileList); + } + else { + //vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_tilesets) + "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList); + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList); + } + } + 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", &vctFileList); + } + } + if(networkGameDataSynchCheckOkMap == false) { + vctFileList.push_back(std::pair(Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir),mapCRC)); + } + + //for(int i = 0; i < vctFileList.size(); i++) + //{ + NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), 1, vctFileList[0].second, vctFileList[0].first); + sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck); + //} + } + } } - *(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()])=switchSetupRequest; - - if(mutex != NULL) mutex->v(); } break; - } - case nmtReady: - { - // its simply ignored here. Probably we are starting a game - break; - } - default: - { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(gotIntro == true) { - //throw runtime_error("Unexpected message in connection slot: " + intToStr(networkMessageType)); - string sErr = "Unexpected message in connection slot: " + intToStr(networkMessageType); - //sendTextMessage(sErr,-1); - //DisplayErrorMessage(sErr); - threadErrorList.push_back(sErr); - return; - } - else { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got invalid message type before intro, disconnecting socket.\n",__FILE__,__FUNCTION__,__LINE__); - close(); + case nmtSynchNetworkGameDataFileCRCCheck: + { + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck\n",__FILE__,__FUNCTION__); + + NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck; + if(receiveMessage(&networkMessageSynchNetworkGameDataFileCRCCheck)) + { + int fileIndex = networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex(); + NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), fileIndex, vctFileList[fileIndex-1].second, vctFileList[fileIndex-1].first); + sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck); } } + break; + + case nmtSynchNetworkGameDataFileGet: + { + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileGet\n",__FILE__,__FUNCTION__); + + NetworkMessageSynchNetworkGameDataFileGet networkMessageSynchNetworkGameDataFileGet; + if(receiveMessage(&networkMessageSynchNetworkGameDataFileGet)) { + FileTransferInfo fileInfo; + fileInfo.hostType = eServer; + //fileInfo.serverIP = this->ip.getString(); + fileInfo.serverPort = Config::getInstance().getInt("ServerPort",intToStr(GameConstants::serverPort).c_str()); + fileInfo.fileName = networkMessageSynchNetworkGameDataFileGet.getFileName(); + + FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo); + fileXferThread->start(); + } + } + break; + + case nmtSwitchSetupRequest: + { + SwitchSetupRequest switchSetupRequest; + if(receiveMessage(&switchSetupRequest)) { + Mutex *mutex = getServerSynchAccessor(); + if(mutex != NULL) mutex->p(); + + if(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]==NULL) { + serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]= new SwitchSetupRequest(); + } + *(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()])=switchSetupRequest; + + if(mutex != NULL) mutex->v(); + } + break; + } + case nmtReady: + { + // its simply ignored here. Probably we are starting a game + break; + } + default: + { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(gotIntro == true) { + //throw runtime_error("Unexpected message in connection slot: " + intToStr(networkMessageType)); + string sErr = "Unexpected message in connection slot: " + intToStr(networkMessageType); + //sendTextMessage(sErr,-1); + //DisplayErrorMessage(sErr); + threadErrorList.push_back(sErr); + return; + } + else { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got invalid message type before intro, disconnecting socket.\n",__FILE__,__FUNCTION__,__LINE__); + close(); + } + } + } } if(gotIntro == false && difftime(time(NULL),connectedTime) > GameConstants::maxClientConnectHandshakeSecs) { @@ -506,6 +512,8 @@ void ConnectionSlot::update(bool checkForNewClients) { close(); } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } } catch(const exception &ex) { diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index dd49d3fa8..02271a75d 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -39,7 +39,7 @@ namespace Glest{ namespace Game{ bool enabledThreadedClientCommandBroadcast = false; // The maximum amount of network update iterations a client is allowed to fall behind -int maxFrameCountLagAllowed = 20; +int maxFrameCountLagAllowed = 30; // 65% of max we warn all users about the lagged client double warnFrameCountLagPercent = 0.65; // Should we wait for lagged clients instead of disconnect them? @@ -242,9 +242,9 @@ bool ServerInterface::clientLagCheck(ConnectionSlot* connectionSlot) { msgTemplate = "%s exceeded max allowed LAG count of %d, clientLag = %d, pausing game to wait for client to catch up..."; } #ifdef WIN32 - _snprintf(szBuf,4095,msgTemplate,Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str()).c_str(),maxFrameCountLagAllowed,clientLagCount); + _snprintf(szBuf,4095,msgTemplate,connectionSlot->getName().c_str() ,maxFrameCountLagAllowed,clientLagCount); #else - snprintf(szBuf,4095,msgTemplate,Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str()).c_str(),maxFrameCountLagAllowed,clientLagCount); + snprintf(szBuf,4095,msgTemplate,connectionSlot->getName().c_str(),maxFrameCountLagAllowed,clientLagCount); #endif SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,szBuf); @@ -282,10 +282,11 @@ bool ServerInterface::clientLagCheck(ConnectionSlot* connectionSlot) { return clientLagExceeded; } -void ServerInterface::signalClientReceiveCommands(ConnectionSlot* connectionSlot, +bool ServerInterface::signalClientReceiveCommands(ConnectionSlot* connectionSlot, int slotIndex, bool socketTriggered, ConnectionSlotEvent &event) { + bool slotSignalled = false; //bool socketTriggered = (connectionSlot != NULL && connectionSlot->getSocket() != NULL ? socketTriggeredList[connectionSlot->getSocket()->getSocketId()] : false); //ConnectionSlotEvent &event = eventList[i]; event.eventType = eReceiveSocketData; @@ -294,13 +295,19 @@ void ServerInterface::signalClientReceiveCommands(ConnectionSlot* connectionSlot event.socketTriggered = socketTriggered; event.triggerId = slotIndex; - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); // Step #1 tell all connection slot worker threads to receive socket data if(connectionSlot != NULL) { - connectionSlot->signalUpdate(&event); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); + if(socketTriggered == true || connectionSlot->isConnected() == false) { + connectionSlot->signalUpdate(&event); + slotSignalled = true; + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); + } } + + return slotSignalled; } void ServerInterface::updateSocketTriggeredList(std::map &socketTriggeredList) { @@ -308,7 +315,7 @@ void ServerInterface::updateSocketTriggeredList(std::map & for(int i= 0; i < GameConstants::maxPlayers; ++i) { ConnectionSlot* connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->getSocket() != NULL && - slots[i]->getSocket()->getSocketId() > 0) { + slots[i]->getSocket()->isSocketValid() == true) { socketTriggeredList[connectionSlot->getSocket()->getSocketId()] = false; } } @@ -328,6 +335,8 @@ void ServerInterface::update() { if(hasData) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] hasData == true\n",__FILE__,__FUNCTION__); if(gameHasBeenInitiated == false || hasData == true) { + std::map mapSlotSignalledList; + // Step #1 tell all connection slot worker threads to receive socket data bool checkForNewClients = true; for(int i= 0; igetSocket() != NULL ? socketTriggeredList[connectionSlot->getSocket()->getSocketId()] : false); ConnectionSlotEvent &event = eventList[i]; - signalClientReceiveCommands(connectionSlot,i,socketTriggered,event); + mapSlotSignalledList[i] = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event); } SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); @@ -349,7 +358,9 @@ void ServerInterface::update() { // Examine all threads for completion of delegation for(int i= 0; i< GameConstants::maxPlayers; ++i) { ConnectionSlot* connectionSlot = slots[i]; - if(connectionSlot != NULL && slotsCompleted.find(i) == slotsCompleted.end()) { + if(connectionSlot != NULL && + mapSlotSignalledList[i] == true && + slotsCompleted.find(i) == slotsCompleted.end()) { std::vector errorList = connectionSlot->getThreadErrorList(); // Show any collected errors from threads if(errorList.size() > 0) { @@ -360,16 +371,16 @@ void ServerInterface::update() { connectionSlot->clearThreadErrorList(); } - // Not done waiting for data yet if(connectionSlot->updateCompleted() == false) { threadsDone = false; + sleep(0); break; } else { // New lag check bool clientLagExceeded = false; - if(connectionSlot->isConnected() == true) { + if(gameHasBeenInitiated == true && connectionSlot->isConnected() == true) { clientLagExceeded = clientLagCheck(connectionSlot); } // If the client has exceeded lag and the server wants @@ -379,6 +390,7 @@ void ServerInterface::update() { bool socketTriggered = (connectionSlot != NULL && connectionSlot->getSocket() != NULL ? socketTriggeredList[connectionSlot->getSocket()->getSocketId()] : false); ConnectionSlotEvent &event = eventList[i]; signalClientReceiveCommands(connectionSlot,i,socketTriggered,event); + sleep(0); } else { slotsCompleted[i] = true; @@ -386,32 +398,34 @@ void ServerInterface::update() { } } } - sleep(0); } - // Step #3 dispatch network commands to the pending list so that they are done in proper order - for(int i= 0; i< GameConstants::maxPlayers; ++i) { - ConnectionSlot* connectionSlot= slots[i]; - if(connectionSlot != NULL && connectionSlot->isConnected() == true) { - if(connectionSlot->getPendingNetworkCommandList().size() > 0) { - // New lag check - bool clientLagExceeded = clientLagCheck(connectionSlot); - if(clientLagExceeded) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d, clientLagExceeded = %d\n",__FILE__,__FUNCTION__,__LINE__,i,clientLagExceeded); - } - else { - vector vctPendingNetworkCommandList = connectionSlot->getPendingNetworkCommandList(); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - for(int idx = 0; idx < vctPendingNetworkCommandList.size(); ++idx) { - NetworkCommand &cmd = vctPendingNetworkCommandList[idx]; - this->requestCommand(&cmd); + // Step #3 dispatch network commands to the pending list so that they are done in proper order + if(gameHasBeenInitiated == true) { + for(int i= 0; i< GameConstants::maxPlayers; ++i) { + ConnectionSlot* connectionSlot= slots[i]; + if(connectionSlot != NULL && connectionSlot->isConnected() == true) { + if(connectionSlot->getPendingNetworkCommandList().size() > 0) { + // New lag check + bool clientLagExceeded = clientLagCheck(connectionSlot); + if(clientLagExceeded) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d, clientLagExceeded = %d\n",__FILE__,__FUNCTION__,__LINE__,i,clientLagExceeded); + } + else { + vector vctPendingNetworkCommandList = connectionSlot->getPendingNetworkCommandList(); + + for(int idx = 0; idx < vctPendingNetworkCommandList.size(); ++idx) { + NetworkCommand &cmd = vctPendingNetworkCommandList[idx]; + this->requestCommand(&cmd); + } + connectionSlot->clearPendingNetworkCommandList(); } - connectionSlot->clearPendingNetworkCommandList(); } } } - } - + } SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); // Step #4 dispatch pending chat messages diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index 13c99cd6e..fd2a6b8af 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -82,7 +82,7 @@ public: int getCurrentFrameCount() const { return currentFrameCount; } bool clientLagCheck(ConnectionSlot* connectionSlot); - void signalClientReceiveCommands(ConnectionSlot* connectionSlot, + bool signalClientReceiveCommands(ConnectionSlot* connectionSlot, int slotIndex, bool socketTriggered, ConnectionSlotEvent &event); diff --git a/source/shared_lib/sources/platform/common/base_thread.cpp b/source/shared_lib/sources/platform/common/base_thread.cpp index 150407c86..e947dc794 100644 --- a/source/shared_lib/sources/platform/common/base_thread.cpp +++ b/source/shared_lib/sources/platform/common/base_thread.cpp @@ -100,7 +100,7 @@ void BaseThread::shutdownAndWait(BaseThread *pThread) { pThread->signalQuit(); //sleep(0); - for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 5; ) { + for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 7; ) { if(pThread->getRunningStatus() == false) { break; } diff --git a/source/shared_lib/sources/util/util.cpp b/source/shared_lib/sources/util/util.cpp index f0f67b024..342b18429 100644 --- a/source/shared_lib/sources/util/util.cpp +++ b/source/shared_lib/sources/util/util.cpp @@ -117,6 +117,9 @@ std::string SystemFlags::getHTTP(std::string URL,CURL *handle) { char errbuf[CURL_ERROR_SIZE]=""; curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errbuf); + // max 5 seconds to connect to the URL + curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, 5); + /* get contents from the URL */ CURLcode result = curl_easy_perform(handle); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] return code [%d] [%s]\n",__FILE__,__FUNCTION__,__LINE__,result,errbuf);