From 4df997d0ca2bde1dfcfdb1da3e07c06ef73bc6b0 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Sat, 24 Sep 2011 07:46:56 +0000 Subject: [PATCH] - initial work for a headless server. Currently this code allows you to launch a server with the commandline option: --masterserver-mode The first client that connects to the server is the administrator and is able to change most settings and launch the game. Still lots of work to do but this is a start. --- source/glest_game/game/game.cpp | 22 +- source/glest_game/game/game_settings.h | 6 + source/glest_game/main/main.cpp | 6 + source/glest_game/main/program.cpp | 5 +- source/glest_game/main/program.h | 2 +- source/glest_game/menu/main_menu.cpp | 28 +- source/glest_game/menu/main_menu.h | 1 + .../menu/menu_state_connected_game.cpp | 914 +++++++++++++++++- .../menu/menu_state_connected_game.h | 14 + .../menu/menu_state_custom_game.cpp | 85 +- .../glest_game/menu/menu_state_custom_game.h | 8 +- .../glest_game/network/client_interface.cpp | 26 + source/glest_game/network/client_interface.h | 8 +- source/glest_game/network/connection_slot.cpp | 45 + source/glest_game/network/connection_slot.h | 3 + source/glest_game/network/network_message.cpp | 3 + source/glest_game/network/network_message.h | 1 + .../glest_game/network/server_interface.cpp | 3 +- source/glest_game/network/server_interface.h | 9 + 19 files changed, 1149 insertions(+), 40 deletions(-) diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 9ac4d33d7..e5bca3df5 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -1151,7 +1151,27 @@ void Game::render() { renderFps++; totalRenderFps++; - renderWorker(); + + NetworkManager &networkManager= NetworkManager::getInstance(); + if(networkManager.getNetworkRole() != nrServer || gameSettings.getMasterserver_admin() == -1) { + renderWorker(); + } + else { + // In masterserver mode quit game if no network players left + ServerInterface *server = NetworkManager::getInstance().getServerInterface(); + int connectedClients=0; + for(int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex()); + if(slot != NULL && slot->isConnected() == true) { + connectedClients++; + } + } + + if(connectedClients == 0) { + quitTriggeredIndicator = true; + } + } } void Game::renderWorker() { diff --git a/source/glest_game/game/game_settings.h b/source/glest_game/game/game_settings.h index 773f2da20..d283f714a 100644 --- a/source/glest_game/game/game_settings.h +++ b/source/glest_game/game/game_settings.h @@ -78,6 +78,7 @@ private: vector > factionCRCList; int aiAcceptSwitchTeamPercentChance; + int masterserver_admin; public: @@ -114,6 +115,7 @@ public: techCRC = 0; factionCRCList.clear(); aiAcceptSwitchTeamPercentChance = 30; + masterserver_admin = -1; } // default copy constructor will do fine, and will maintain itself ;) @@ -237,6 +239,9 @@ public: int getAiAcceptSwitchTeamPercentChance() const { return aiAcceptSwitchTeamPercentChance;} void setAiAcceptSwitchTeamPercentChance(int value) { aiAcceptSwitchTeamPercentChance = value; } + int getMasterserver_admin() const { return masterserver_admin;} + void setMasterserver_admin(int value) { masterserver_admin = value; } + string toString() const { string result = ""; @@ -282,6 +287,7 @@ public: } result += "aiAcceptSwitchTeamPercentChance = " + intToStr(aiAcceptSwitchTeamPercentChance) + "\n"; + result += "masterserver_admin = " + intToStr(masterserver_admin) + "\n"; return result; } diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 1c54308be..5865a519f 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -102,6 +102,7 @@ const char *GAME_ARGS[] = { "--autostart-lastgame", "--connecthost", "--starthost", + "--masterserver-mode", "--load-scenario", "--preview-map", "--version", @@ -145,6 +146,7 @@ enum GAME_ARG_TYPE { GAME_ARG_AUTOSTART_LASTGAME, GAME_ARG_CLIENT, GAME_ARG_SERVER, + GAME_ARG_MASTERSERVER_MODE, GAME_ARG_LOADSCENARIO, GAME_ARG_PREVIEW_MAP, GAME_ARG_VERSION, @@ -1010,6 +1012,7 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) { printf("\n%s\t\tAutomatically starts a game with the last game settings you played.",GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME]); printf("\n%s=x\t\t\tAuto connects to a network server at IP or hostname x",GAME_ARGS[GAME_ARG_CLIENT]); printf("\n%s\t\t\tAuto creates a network server.",GAME_ARGS[GAME_ARG_SERVER]); + printf("\n%s\t\t\tRuns as a masterserver.",GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]); printf("\n%s=x\t\tAuto loads the specified scenario by scenario name.",GAME_ARGS[GAME_ARG_LOADSCENARIO]); printf("\n%s=x\t\tAuto Preview the specified map by map name.",GAME_ARGS[GAME_ARG_PREVIEW_MAP]); printf("\n%s\t\t\tdisplays the version string of this program.",GAME_ARGS[GAME_ARG_VERSION]); @@ -3125,6 +3128,9 @@ int glestMain(int argc, char** argv) { if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SERVER]) == true) { program->initServer(mainWindow,false,true); } + else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) { + program->initServer(mainWindow,false,true,true); + } else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME])) == true) { program->initServer(mainWindow,true,false); } diff --git a/source/glest_game/main/program.cpp b/source/glest_game/main/program.cpp index fd78f4865..f8a5b4678 100644 --- a/source/glest_game/main/program.cpp +++ b/source/glest_game/main/program.cpp @@ -181,13 +181,14 @@ void Program::initNormal(WindowGl *window){ if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } -void Program::initServer(WindowGl *window, bool autostart,bool openNetworkSlots) { +void Program::initServer(WindowGl *window, bool autostart,bool openNetworkSlots, + bool masterserverMode) { MainMenu* mainMenu= NULL; init(window); mainMenu= new MainMenu(this); setState(mainMenu); - mainMenu->setState(new MenuStateCustomGame(this, mainMenu, openNetworkSlots, false, autostart)); + mainMenu->setState(new MenuStateCustomGame(this, mainMenu, openNetworkSlots, false, autostart, NULL, masterserverMode)); } void Program::initServer(WindowGl *window, GameSettings *settings) { diff --git a/source/glest_game/main/program.h b/source/glest_game/main/program.h index 093eacfc6..31ef8e00d 100644 --- a/source/glest_game/main/program.h +++ b/source/glest_game/main/program.h @@ -152,7 +152,7 @@ public: GraphicMessageBox * getMsgBox() { return &msgBox; } void initNormal(WindowGl *window); - void initServer(WindowGl *window,bool autostart=false,bool openNetworkSlots=false); + void initServer(WindowGl *window,bool autostart=false,bool openNetworkSlots=false,bool masterserverMode=false); void initServer(WindowGl *window, GameSettings *settings); void initClient(WindowGl *window, const Ip &serverIp); void initScenario(WindowGl *window, string autoloadScenarioName); diff --git a/source/glest_game/menu/main_menu.cpp b/source/glest_game/menu/main_menu.cpp index d585edb42..6cee163ef 100644 --- a/source/glest_game/menu/main_menu.cpp +++ b/source/glest_game/menu/main_menu.cpp @@ -94,24 +94,26 @@ void MainMenu::render() { canRender(); incrementFps(); - renderer.clearBuffers(); + if(state->isMasterserverMode() == false) { + renderer.clearBuffers(); - //3d - renderer.reset3dMenu(); + //3d + renderer.reset3dMenu(); - renderer.clearZBuffer(); - renderer.loadCameraMatrix(menuBackground.getCamera()); - renderer.renderMenuBackground(&menuBackground); - renderer.renderParticleManager(rsMenu); + renderer.clearZBuffer(); + renderer.loadCameraMatrix(menuBackground.getCamera()); + renderer.renderMenuBackground(&menuBackground); + renderer.renderParticleManager(rsMenu); - //2d - renderer.reset2d(); - state->render(); - renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); + //2d + renderer.reset2d(); + state->render(); + renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); - renderer.renderFPSWhenEnabled(lastFps); + renderer.renderFPSWhenEnabled(lastFps); - renderer.swapBuffers(); + renderer.swapBuffers(); + } } //syncronus update diff --git a/source/glest_game/menu/main_menu.h b/source/glest_game/menu/main_menu.h index efe6368fd..fa69ff925 100644 --- a/source/glest_game/menu/main_menu.h +++ b/source/glest_game/menu/main_menu.h @@ -139,6 +139,7 @@ public: virtual void keyPress(SDL_KeyboardEvent c){}; virtual void keyUp(SDL_KeyboardEvent key){}; + virtual bool isMasterserverMode() const {return false;} const Camera *getCamera() const {return &camera;} virtual bool isInSpecialKeyCaptureEvent() { return false; } diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 90d510e29..8edc86df9 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -199,6 +199,7 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM listBoxEnableSwitchTeamMode.pushBackItem(lang.get("Yes")); listBoxEnableSwitchTeamMode.pushBackItem(lang.get("No")); listBoxEnableSwitchTeamMode.setSelectedItemIndex(1); + listBoxEnableSwitchTeamMode.setEditable(false); labelAISwitchTeamAcceptPercent.registerGraphicComponent(containerName,"labelAISwitchTeamAcceptPercent"); labelAISwitchTeamAcceptPercent.init(xoffset+250, aHeadPos+40, 80); @@ -210,6 +211,7 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM listBoxAISwitchTeamAcceptPercent.pushBackItem(intToStr(i)); } listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(30)); + listBoxAISwitchTeamAcceptPercent.setEditable(false); labelPathFinderType.registerGraphicComponent(containerName,"labelPathFinderType"); labelPathFinderType.init(xoffset+450, aHeadPos, 80); @@ -432,6 +434,45 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM //init controllers listBoxControls[0].setSelectedItemIndex(ctHuman); + + //map listBox + // put them all in a set, to weed out duplicates (gbm & mgm with same name) + // will also ensure they are alphabetically listed (rather than how the OS provides them) + set allMaps; + findAll(config.getPathListForType(ptMaps), "*.gbm", results, true, false); + copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); + results.clear(); + findAll(config.getPathListForType(ptMaps), "*.mgm", results, true, false); + copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); + results.clear(); + + if (allMaps.empty()) { + throw runtime_error("No maps were found!"); + } + copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); + mapFiles = results; + + copy(mapFiles.begin(), mapFiles.end(), std::back_inserter(playerSortedMaps[0])); + copy(playerSortedMaps[0].begin(), playerSortedMaps[0].end(), std::back_inserter(formattedPlayerSortedMaps[0])); + std::for_each(formattedPlayerSortedMaps[0].begin(), formattedPlayerSortedMaps[0].end(), FormatString()); + + for(int i= 0; i < mapFiles.size(); i++){// fetch info and put map in right list + loadMapInfo(Map::getMapPath(mapFiles.at(i), "", false), &mapInfo, false); + playerSortedMaps[mapInfo.players].push_back(mapFiles.at(i)); + formattedPlayerSortedMaps[mapInfo.players].push_back(formatString(mapFiles.at(i))); + formattedMapFiles.push_back(formatString(mapFiles.at(i))); + //if(config.getString("InitialMap", "Conflict") == formattedPlayerSortedMaps[mapInfo.players].back()){ + // initialMapSelection= i; + //} + } + //listBoxMap.setItems(formattedPlayerSortedMaps[0]); + listBoxMap.setItems(formattedMapFiles); + + buttonPlayNow.registerGraphicComponent(containerName,"buttonPlayNow"); + buttonPlayNow.init(200, 180, 125); + buttonPlayNow.setText(lang.get("PlayNow")); + buttonPlayNow.setVisible(false); + chatManager.init(&console, -1,true); GraphicComponent::applyAllCustomProperties(containerName); @@ -439,8 +480,24 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM //tileset listBox findDirs(config.getPathListForType(ptTilesets), tilesetFiles); + std::vector tilesetsFormatted = tilesetFiles; + std::for_each(tilesetsFormatted.begin(), tilesetsFormatted.end(), FormatString()); + listBoxTileset.setItems(tilesetsFormatted); + findDirs(config.getPathListForType(ptTechs), techTreeFiles); + //reloadFactions(true); + int initialTechSelection=0; + std::vector techsFormatted = techTreeFiles; + for(int i= 0; i < techsFormatted.size(); i++){ + techsFormatted.at(i)= formatString(techsFormatted.at(i)); + if(config.getString("InitialTechTree", "Megapack") == techsFormatted.at(i)){ + initialTechSelection= i; + } + } + listBoxTechTree.setItems(techsFormatted); + listBoxTechTree.setSelectedItemIndex(initialTechSelection); + if(config.getBool("EnableFTPXfer","true") == true) { ClientInterface *clientInterface = networkManager.getClientInterface(); @@ -722,20 +779,20 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ if (initialSettingsReceivedFromServer == false) return; // Only allow changes after we get game settings from the server - if(clientInterface->isConnected() == true){ + if(clientInterface->isConnected() == true) { int myCurrentIndex= -1; - for(int i= 0; i < GameConstants::maxPlayers; ++i){// find my current index by looking at editable listBoxes - if(listBoxFactions[i].getEditable()){ + for(int i= 0; i < GameConstants::maxPlayers; ++i) {// find my current index by looking at editable listBoxes + if(listBoxFactions[i].getEditable() && clientInterface->getGameSettings()->getThisFactionIndex() == i) { myCurrentIndex= i; } } if(myCurrentIndex != -1) - for(int i= 0; i < GameConstants::maxPlayers; ++i){ - if(listBoxFactions[i].getEditable()){ - if(listBoxFactions[i].mouseClick(x, y)){ + for(int i= 0; i < GameConstants::maxPlayers; ++i) { + if(listBoxFactions[i].getEditable() && clientInterface->getGameSettings()->getThisFactionIndex() == i) { + if(listBoxFactions[i].mouseClick(x, y)) { soundRenderer.playFx(coreData.getClickSoundA()); ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface(); - if(clientInterface->isConnected()){ + if(clientInterface->isConnected()) { clientInterface->setGameSettingsReceived(false); clientInterface->sendSwitchSetupRequest( listBoxFactions[i].getSelectedItem(), @@ -751,7 +808,7 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ break; } } - if(listBoxTeams[i].getEditable()){ + if(listBoxTeams[i].getEditable() && clientInterface->getGameSettings()->getThisFactionIndex() == i) { if(listBoxTeams[i].mouseClick(x, y)){ soundRenderer.playFx(coreData.getClickSoundA()); if(clientInterface->isConnected()){ @@ -840,10 +897,783 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ switchSetupRequestFlagType=ssrft_None; } } + + if(isMasterserverAdmin() == true) { + //printf("#1 admin key [%d] client key [%d]\n",settings->getMasterserver_admin(),clientInterface->getSessionKey()); + mouseClickAdmin(x, y, mouseButton); + } } if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); } +bool MenuStateConnectedGame::isMasterserverAdmin() { + bool result = false; + + ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface(); + if(clientInterface != NULL && clientInterface->isConnected()) { + const GameSettings *settings = clientInterface->getGameSettings(); + if(settings != NULL) { + //printf("#1 admin key [%d] client key [%d]\n",settings->getMasterserver_admin(),clientInterface->getSessionKey()); + + if(settings->getMasterserver_admin() == clientInterface->getSessionKey()) { + result = true; + } + } + } + + return result; +} + +void MenuStateConnectedGame::broadCastGameSettingsToMasterserver() { + NetworkManager &networkManager= NetworkManager::getInstance(); + ClientInterface *clientInterface = networkManager.getClientInterface(); + + GameSettings gameSettings = *clientInterface->getGameSettings(); + loadGameSettings(&gameSettings); + + //printf("Client sending map [%s] admin key [%d]\n",gameSettings.getMap().c_str(),gameSettings.getMasterserver_admin()); + + //clientInterface->setGameSettings(&gameSettings); + clientInterface->broadcastGameSetup(&gameSettings); + +} + +void MenuStateConnectedGame::mouseClickAdmin(int x, int y, MouseButton mouseButton) { + + try { + CoreData &coreData= CoreData::getInstance(); + SoundRenderer &soundRenderer= SoundRenderer::getInstance(); + //int oldListBoxMapfilterIndex=listBoxMapFilter.getSelectedItemIndex(); + + if(buttonPlayNow.mouseClick(x,y) && buttonPlayNow.getEnabled()) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + PlayNow(true); + return; + } +// else if(buttonRestoreLastSettings.mouseClick(x,y) && buttonRestoreLastSettings.getEnabled()) { +// RestoreLastGameSettings(); +// } +// else + else if(listBoxMap.mouseClick(x, y)){ + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n", getCurrentMapFile().c_str()); + + //MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + + loadMapInfo(Map::getMapPath(getCurrentMapFile(),"",false), &mapInfo, true); + labelMapInfo.setText(mapInfo.desc); + //updateControlers(); + //updateNetworkSlots(); + + //if(listBoxPublishServer.getSelectedItemIndex() == 0) { + // needToRepublishToMasterserver = true; + //} + + //if(hasNetworkGameSettings() == true) { + //delay publishing for 5 seconds + // needToPublishDelayed=true; + // mapPublishingDelayTimer=time(NULL); + //} + + broadCastGameSettingsToMasterserver(); + } + else if(listBoxFogOfWar.mouseClick(x, y)) { + //MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + +// cleanupMapPreviewTexture(); +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// if(hasNetworkGameSettings() == true) { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } + + broadCastGameSettingsToMasterserver(); + } + else if(listBoxAllowObservers.mouseClick(x, y)) { +// MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); +// +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// reloadFactions(true); +// +// if(hasNetworkGameSettings() == true) { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } + + broadCastGameSettingsToMasterserver(); + } + else if(listBoxEnableObserverMode.mouseClick(x, y)) { + //MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// if(hasNetworkGameSettings() == true) +// { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } + + broadCastGameSettingsToMasterserver(); + } + else if (listBoxEnableSwitchTeamMode.mouseClick(x, y)) { + //MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// if(hasNetworkGameSettings() == true) +// { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } + + broadCastGameSettingsToMasterserver(); + } + else if(listBoxAISwitchTeamAcceptPercent.getEnabled() && listBoxAISwitchTeamAcceptPercent.mouseClick(x, y)) { + //MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// if(hasNetworkGameSettings() == true) +// { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } + + broadCastGameSettingsToMasterserver(); + } +// else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxPathFinderType.mouseClick(x, y)) { +// MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); +// +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// if(hasNetworkGameSettings() == true) +// { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } +// } +// else if (listBoxAdvanced.mouseClick(x, y)) { +// //TODO +// } + else if(listBoxTileset.mouseClick(x, y)) { + //MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// if(hasNetworkGameSettings() == true) +// { +// +// //delay publishing for 5 seconds +// needToPublishDelayed=true; +// mapPublishingDelayTimer=time(NULL); +// } + + broadCastGameSettingsToMasterserver(); + } +// else if(listBoxMapFilter.mouseClick(x, y)){ +// MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); +// switchToNextMapGroup(listBoxMapFilter.getSelectedItemIndex()-oldListBoxMapfilterIndex); +// +// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n", getCurrentMapFile().c_str()); +// +// loadMapInfo(Map::getMapPath(getCurrentMapFile()), &mapInfo, true); +// labelMapInfo.setText(mapInfo.desc); +// updateControlers(); +// updateNetworkSlots(); +// +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// if(hasNetworkGameSettings() == true) +// { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } +// } + else if(listBoxTechTree.mouseClick(x, y)) { + reloadFactions(false); + + //MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + + //if(listBoxPublishServer.getSelectedItemIndex() == 0) { + // needToRepublishToMasterserver = true; + //} + + //if(hasNetworkGameSettings() == true) + //{ + // needToSetChangedGameSettings = true; + // lastSetChangedGameSettings = time(NULL); + //} + + broadCastGameSettingsToMasterserver(); + } +// else if(listBoxPublishServer.mouseClick(x, y) && listBoxPublishServer.getEditable()) { +// MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); +// needToRepublishToMasterserver = true; +// soundRenderer.playFx(coreData.getClickSoundC()); +// +// ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); +// serverInterface->setPublishEnabled(listBoxPublishServer.getSelectedItemIndex() == 0); +// } + else if(listBoxNetworkPauseGameForLaggedClients.mouseClick(x, y)) { +// MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); +// +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// if(hasNetworkGameSettings() == true) +// { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } + + soundRenderer.playFx(coreData.getClickSoundC()); + + broadCastGameSettingsToMasterserver(); + } + else { + NetworkManager &networkManager= NetworkManager::getInstance(); + ClientInterface* clientInterface= networkManager.getClientInterface(); + + for(int i=0; igetMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + + //if (listBoxAdvanced.getSelectedItemIndex() == 1) { + // set multiplier + if(listBoxRMultiplier[i].mouseClick(x, y)) { + broadCastGameSettingsToMasterserver(); + } + //} + + //ensure thet only 1 human player is present + if(listBoxControls[i].mouseClick(x, y)) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + //look for human players +// int humanIndex1= -1; +// int humanIndex2= -1; +// for(int j=0; j(listBoxControls[j].getSelectedItemIndex()); +// if(ct == ctHuman) { +// if(humanIndex1 == -1) { +// humanIndex1= j; +// } +// else { +// humanIndex2= j; +// } +// } +// } +// +// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] humanIndex1 = %d, humanIndex2 = %d\n",__FILE__,__FUNCTION__,__LINE__,humanIndex1,humanIndex2); +// +// //no human +// if(humanIndex1 == -1 && humanIndex2 == -1) { +// listBoxControls[i].setSelectedItemIndex(ctHuman); +// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] i = %d, labelPlayerNames[i].getText() [%s]\n",__FILE__,__FUNCTION__,__LINE__,i,labelPlayerNames[i].getText().c_str()); +// } +// //2 humans +// else if(humanIndex1 != -1 && humanIndex2 != -1) { +// int closeSlotIndex = (humanIndex1 == i ? humanIndex2: humanIndex1); +// int humanSlotIndex = (closeSlotIndex == humanIndex1 ? humanIndex2 : humanIndex1); +// +// string origPlayName = labelPlayerNames[closeSlotIndex].getText(); +// +// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] closeSlotIndex = %d, origPlayName [%s]\n",__FILE__,__FUNCTION__,__LINE__,closeSlotIndex,origPlayName.c_str()); +// +// listBoxControls[closeSlotIndex].setSelectedItemIndex(ctClosed); +// labelPlayerNames[humanSlotIndex].setText((origPlayName != "" ? origPlayName : getHumanPlayerName())); +// } +// updateNetworkSlots(); +// +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// if(hasNetworkGameSettings() == true) { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } +// updateResourceMultiplier(i); + + broadCastGameSettingsToMasterserver(); + } +// else if(buttonClearBlockedPlayers.mouseClick(x, y)) { +// ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); +// if(serverInterface != NULL) { +// ServerSocket *serverSocket = serverInterface->getServerSocket(); +// if(serverSocket != NULL) { +// serverSocket->clearBlockedIPAddress(); +// } +// } +// } +// else if(buttonBlockPlayers[i].mouseClick(x, y)) { +// ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); +// if(serverInterface != NULL) { +// if(serverInterface->getSlot(i) != NULL && +// serverInterface->getSlot(i)->isConnected()) { +// +// ServerSocket *serverSocket = serverInterface->getServerSocket(); +// if(serverSocket != NULL) { +// serverSocket->addIPAddressToBlockedList(serverInterface->getSlot(i)->getIpAddress()); +// +// Lang &lang= Lang::getInstance(); +// const vector languageList = serverInterface->getGameSettings()->getUniqueNetworkPlayerLanguages(); +// for(unsigned int j = 0; j < languageList.size(); ++j) { +// char szMsg[1024]=""; +// if(lang.hasString("BlockPlayerServerMsg",languageList[j]) == true) { +// sprintf(szMsg,lang.get("BlockPlayerServerMsg",languageList[j]).c_str(),serverInterface->getSlot(i)->getIpAddress().c_str()); +// } +// else { +// sprintf(szMsg,"The server has temporarily blocked IP Address [%s] from this game.",serverInterface->getSlot(i)->getIpAddress().c_str()); +// } +// +// serverInterface->sendTextMessage(szMsg,-1, true,languageList[j]); +// } +// sleep(1); +// serverInterface->getSlot(i)->close(); +// } +// } +// } +// } + else if(clientInterface->getGameSettings()->getThisFactionIndex() != i && listBoxFactions[i].mouseClick(x, y)) { + // Disallow CPU players to be observers + if(factionFiles[listBoxFactions[i].getSelectedItemIndex()] == formatString(GameConstants::OBSERVER_SLOTNAME) && + (listBoxControls[i].getSelectedItemIndex() == ctCpuEasy || listBoxControls[i].getSelectedItemIndex() == ctCpu || + listBoxControls[i].getSelectedItemIndex() == ctCpuUltra || listBoxControls[i].getSelectedItemIndex() == ctCpuMega)) { + listBoxFactions[i].setSelectedItemIndex(0); + } + // + +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// if(hasNetworkGameSettings() == true) +// { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } + + broadCastGameSettingsToMasterserver(); + } + else if(clientInterface->getGameSettings()->getThisFactionIndex() != i && listBoxTeams[i].mouseClick(x, y)) { + if(factionFiles[listBoxFactions[i].getSelectedItemIndex()] != formatString(GameConstants::OBSERVER_SLOTNAME)) { + if(listBoxTeams[i].getSelectedItemIndex() + 1 != (GameConstants::maxPlayers + fpt_Observer)) { + //lastSelectedTeamIndex[i] = listBoxTeams[i].getSelectedItemIndex(); + } + } + else { + //lastSelectedTeamIndex[i] = -1; + } + +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// if(hasNetworkGameSettings() == true) +// { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL);; +// } + + broadCastGameSettingsToMasterserver(); + } +// else if(labelPlayerNames[i].mouseClick(x, y)) { +// SetActivePlayerNameEditor(); +// } + } + } +// +// if(hasNetworkGameSettings() == true && listBoxPlayerStatus.mouseClick(x,y)) { +// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); +// +// soundRenderer.playFx(coreData.getClickSoundC()); +// if(getNetworkPlayerStatus()==npst_PickSettings) +// { +// listBoxPlayerStatus.setTextColor(Vec3f(1.0f,0.0f,0.0f)); +// listBoxPlayerStatus.setLighted(true); +// } +// else if(getNetworkPlayerStatus()==npst_BeRightBack) +// { +// listBoxPlayerStatus.setTextColor(Vec3f(1.0f,1.0f,0.0f)); +// listBoxPlayerStatus.setLighted(true); +// } +// else if(getNetworkPlayerStatus()==npst_Ready) +// { +// listBoxPlayerStatus.setTextColor(Vec3f(0.0f,1.0f,0.0f)); +// listBoxPlayerStatus.setLighted(false); +// } +// +// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); +// +// if(listBoxPublishServer.getSelectedItemIndex() == 0) { +// needToRepublishToMasterserver = true; +// } +// +// if(hasNetworkGameSettings() == true) { +// needToSetChangedGameSettings = true; +// lastSetChangedGameSettings = time(NULL); +// } +// } + } + catch(const std::exception &ex) { + char szBuf[4096]=""; + sprintf(szBuf,"In [%s::%s %d] Error detected:\n%s\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf); + //showGeneralError=true; + //generalErrorToShow = szBuf; + } + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void MenuStateConnectedGame::PlayNow(bool saveGame) { + if(saveGame == true) { + //saveGameSettingsToFile("lastCustomGamSettings.mgg"); + } + + //forceWaitForShutdown = false; + //closeUnusedSlots(); + CoreData &coreData= CoreData::getInstance(); + SoundRenderer &soundRenderer= SoundRenderer::getInstance(); + soundRenderer.playFx(coreData.getClickSoundC()); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + NetworkManager &networkManager= NetworkManager::getInstance(); + ClientInterface *clientInterface = networkManager.getClientInterface(); + + GameSettings gameSettings = *clientInterface->getGameSettings(); + loadGameSettings(&gameSettings); + + //printf("Client sending map [%s] admin key [%d]\n",gameSettings.getMap().c_str(),gameSettings.getMasterserver_admin()); + + //clientInterface->setGameSettings(&gameSettings); + clientInterface->broadcastGameStart(&gameSettings); +} + +string MenuStateConnectedGame::getCurrentMapFile() { + //int i=listBoxMapFilter.getSelectedItemIndex(); + //int mapIndex=listBoxMap.getSelectedItemIndex(); + //return playerSortedMaps[i].at(mapIndex); + int mapIndex=listBoxMap.getSelectedItemIndex(); + return mapFiles[mapIndex]; +} + +void MenuStateConnectedGame::reloadFactions(bool keepExistingSelectedItem) { + vector results; + Config &config = Config::getInstance(); + + vector techPaths = config.getPathListForType(ptTechs); + for(int idx = 0; idx < techPaths.size(); idx++) { + string &techPath = techPaths[idx]; + endPathWithSlash(techPath); + //findAll(techPath + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "/factions/*.", results, false, false); + findDirs(techPath + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "/factions/", results, false, false); + + if(results.empty() == false) { + break; + } + } + + if(results.empty() == true) { + //throw runtime_error("(2)There are no factions for the tech tree [" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"); + //showGeneralError=true; + //generalErrorToShow = "[#2] There are no factions for the tech tree [" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"; + } + + results.push_back(formatString(GameConstants::RANDOMFACTION_SLOTNAME)); + + // Add special Observer Faction + //Lang &lang= Lang::getInstance(); + if(listBoxAllowObservers.getSelectedItemIndex() == 1) { + results.push_back(formatString(GameConstants::OBSERVER_SLOTNAME)); + } + + factionFiles= results; + for(int i= 0; i 0 ? listBoxFactions[i].getSelectedItem() : ""); + + //printf("[a1] i = %d, originalValue = [%s]\n",i,originalValue.c_str()); + + listBoxFactions[i].setItems(results); + if( keepExistingSelectedItem == false || + (listBoxAllowObservers.getSelectedItemIndex() == 0 && + originalValue == formatString(GameConstants::OBSERVER_SLOTNAME)) ) { + listBoxFactions[i].setSelectedItemIndex(i % results.size()); + + if( originalValue == formatString(GameConstants::OBSERVER_SLOTNAME) && + listBoxFactions[i].getSelectedItem() != formatString(GameConstants::OBSERVER_SLOTNAME)) { + if(listBoxTeams[i].getSelectedItem() == intToStr(GameConstants::maxPlayers + fpt_Observer)) { + listBoxTeams[i].setSelectedItem(intToStr(1)); + } + } + //printf("[b] i = %d, listBoxFactions[i].getSelectedItemIndex() = %d\n",i,listBoxFactions[i].getSelectedItemIndex()); + } + else if(originalIndex < results.size()) { + listBoxFactions[i].setSelectedItemIndex(originalIndex); + + //printf("[c] i = %d, originalIndex = %d\n",i,originalIndex); + } + } +} + +void MenuStateConnectedGame::loadGameSettings(GameSettings *gameSettings) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + + int factionCount= 0; + //ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + + // Test flags values + //gameSettings->setFlagTypes1(ft1_show_map_resources); + // + + //gameSettings->setMapFilterIndex(listBoxMapFilter.getSelectedItemIndex()); + gameSettings->setDescription(formatString(getCurrentMapFile())); + gameSettings->setMap(getCurrentMapFile()); + gameSettings->setTileset(tilesetFiles[listBoxTileset.getSelectedItemIndex()]); + gameSettings->setTech(techTreeFiles[listBoxTechTree.getSelectedItemIndex()]); + + gameSettings->setDefaultUnits(true); + gameSettings->setDefaultResources(true); + gameSettings->setDefaultVictoryConditions(true); + + gameSettings->setFogOfWar(listBoxFogOfWar.getSelectedItemIndex() == 0 || + listBoxFogOfWar.getSelectedItemIndex() == 1 ); + + gameSettings->setAllowObservers(listBoxAllowObservers.getSelectedItemIndex() == 1); + + uint32 valueFlags1 = gameSettings->getFlagTypes1(); + if(listBoxFogOfWar.getSelectedItemIndex() == 1 || + listBoxFogOfWar.getSelectedItemIndex() == 2 ) { + valueFlags1 |= ft1_show_map_resources; + gameSettings->setFlagTypes1(valueFlags1); + } + else { + valueFlags1 &= ~ft1_show_map_resources; + gameSettings->setFlagTypes1(valueFlags1); + } + + gameSettings->setEnableObserverModeAtEndGame(listBoxEnableObserverMode.getSelectedItemIndex() == 0); + gameSettings->setPathFinderType(static_cast(listBoxPathFinderType.getSelectedItemIndex())); + + valueFlags1 = gameSettings->getFlagTypes1(); + if(listBoxEnableSwitchTeamMode.getSelectedItemIndex() == 0) { + valueFlags1 |= ft1_allow_team_switching; + gameSettings->setFlagTypes1(valueFlags1); + } + else { + valueFlags1 &= ~ft1_allow_team_switching; + gameSettings->setFlagTypes1(valueFlags1); + } + gameSettings->setAiAcceptSwitchTeamPercentChance(strToInt(listBoxAISwitchTeamAcceptPercent.getSelectedItem())); + + // First save Used slots + //for(int i=0; i(listBoxControls[i].getSelectedItemIndex()); + + if(ct != ctClosed) { + int slotIndex = factionCount; + + gameSettings->setFactionControl(slotIndex, ct); + if(ct == ctHuman) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, slotIndex = %d, getHumanPlayerName(i) [%s]\n",__FILE__,__FUNCTION__,__LINE__,i,slotIndex,getHumanPlayerName(i).c_str()); + + gameSettings->setThisFactionIndex(slotIndex); + //gameSettings->setNetworkPlayerName(slotIndex, getHumanPlayerName(i)); + gameSettings->setNetworkPlayerStatuses(slotIndex, getNetworkPlayerStatus()); + Lang &lang= Lang::getInstance(); + gameSettings->setNetworkPlayerLanguages(slotIndex, lang.getLanguage()); + } + //else if(serverInterface->getSlot(i) != NULL) { + // gameSettings->setNetworkPlayerLanguages(slotIndex, serverInterface->getSlot(i)->getNetworkPlayerLanguage()); + //} + gameSettings->setResourceMultiplierIndex(slotIndex, listBoxRMultiplier[i].getSelectedItemIndex()); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n",__FILE__,__FUNCTION__,__LINE__,i,factionFiles[listBoxFactions[i].getSelectedItemIndex()].c_str()); + + gameSettings->setFactionTypeName(slotIndex, factionFiles[listBoxFactions[i].getSelectedItemIndex()]); + if(factionFiles[listBoxFactions[i].getSelectedItemIndex()] == formatString(GameConstants::OBSERVER_SLOTNAME)) { + listBoxTeams[i].setSelectedItem(intToStr(GameConstants::maxPlayers + fpt_Observer)); + } +// else if(listBoxTeams[i].getSelectedItem() == intToStr(GameConstants::maxPlayers + fpt_Observer)) { +// if(lastSelectedTeamIndex[i] >= 0 && lastSelectedTeamIndex[i] + 1 != (GameConstants::maxPlayers + fpt_Observer)) { +// if(lastSelectedTeamIndex[i] == 0) { +// lastSelectedTeamIndex[i] = GameConstants::maxPlayers-1; +// } +// else if(lastSelectedTeamIndex[i] == GameConstants::maxPlayers-1) { +// lastSelectedTeamIndex[i] = 0; +// } +// +// listBoxTeams[i].setSelectedItemIndex(lastSelectedTeamIndex[i]); +// } +// else { +// listBoxTeams[i].setSelectedItem(intToStr(1)); +// } +// } + + gameSettings->setTeam(slotIndex, listBoxTeams[i].getSelectedItemIndex()); + gameSettings->setStartLocationIndex(slotIndex, i); + + + if(listBoxControls[i].getSelectedItemIndex() == ctNetwork || listBoxControls[i].getSelectedItemIndex() == ctNetworkUnassigned) { +// if(serverInterface->getSlot(i) != NULL && +// serverInterface->getSlot(i)->isConnected()) { +// +// gameSettings->setNetworkPlayerStatuses(slotIndex,serverInterface->getSlot(i)->getNetworkPlayerStatus()); +// +// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, connectionSlot->getName() [%s]\n",__FILE__,__FUNCTION__,__LINE__,i,serverInterface->getSlot(i)->getName().c_str()); +// +// gameSettings->setNetworkPlayerName(slotIndex, serverInterface->getSlot(i)->getName()); +// labelPlayerNames[i].setText(serverInterface->getSlot(i)->getName()); +// } +// else { +// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, playername unconnected\n",__FILE__,__FUNCTION__,__LINE__,i); +// +// gameSettings->setNetworkPlayerName(slotIndex, GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME); +// labelPlayerNames[i].setText(""); +// } + } + else if (listBoxControls[i].getSelectedItemIndex() != ctHuman) { + AIPlayerCount++; + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, playername is AI (blank)\n",__FILE__,__FUNCTION__,__LINE__,i); + + gameSettings->setNetworkPlayerName(slotIndex, string("AI") + intToStr(AIPlayerCount)); + labelPlayerNames[i].setText(""); + } + + factionCount++; + } + else { + //gameSettings->setNetworkPlayerName(""); + gameSettings->setNetworkPlayerStatuses(factionCount, 0); + labelPlayerNames[i].setText(""); + } + } + + // Next save closed slots + int closedCount = 0; + for(int i = 0; i < GameConstants::maxPlayers; ++i) { + ControlType ct= static_cast(listBoxControls[i].getSelectedItemIndex()); + if(ct == ctClosed) { + int slotIndex = factionCount + closedCount; + + gameSettings->setFactionControl(slotIndex, ct); + gameSettings->setTeam(slotIndex, listBoxTeams[i].getSelectedItemIndex()); + gameSettings->setStartLocationIndex(slotIndex, i); + gameSettings->setResourceMultiplierIndex(slotIndex, 10); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n",__FILE__,__FUNCTION__,__LINE__,i,factionFiles[listBoxFactions[i].getSelectedItemIndex()].c_str()); + + gameSettings->setFactionTypeName(slotIndex, factionFiles[listBoxFactions[i].getSelectedItemIndex()]); + gameSettings->setNetworkPlayerName(slotIndex, "Closed"); + + closedCount++; + } + } + + gameSettings->setFactionCount(factionCount); + + Config &config = Config::getInstance(); + gameSettings->setEnableServerControlledAI(config.getBool("ServerControlledAI","true")); + gameSettings->setNetworkFramePeriod(config.getInt("NetworkSendFrameCount","20")); + gameSettings->setNetworkPauseGameForLaggedClients(((listBoxNetworkPauseGameForLaggedClients.getSelectedItemIndex() != 0))); + + if(hasNetworkGameSettings() == true) { + if( gameSettings->getTileset() != "") { + if(lastCheckedCRCTilesetName != gameSettings->getTileset()) { + //console.addLine("Checking tileset CRC [" + gameSettings->getTileset() + "]"); + lastCheckedCRCTilesetValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + gameSettings->getTileset() + string("/*"), ".xml", NULL, true); + lastCheckedCRCTilesetName = gameSettings->getTileset(); + } + gameSettings->setTilesetCRC(lastCheckedCRCTilesetValue); + } + + if(config.getBool("DisableServerLobbyTechtreeCRCCheck","false") == false) { + if(gameSettings->getTech() != "") { + if(lastCheckedCRCTechtreeName != gameSettings->getTech()) { + //console.addLine("Checking techtree CRC [" + gameSettings->getTech() + "]"); + lastCheckedCRCTechtreeValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/*", ".xml", NULL); + if(lastCheckedCRCTechtreeValue == 0) { + lastCheckedCRCTechtreeValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/*", ".xml", NULL, true); + } + + reloadFactions(true); + factionCRCList.clear(); + for(unsigned int factionIdx = 0; factionIdx < factionFiles.size(); ++factionIdx) { + string factionName = factionFiles[factionIdx]; + if(factionName != GameConstants::RANDOMFACTION_SLOTNAME && + factionName != GameConstants::OBSERVER_SLOTNAME) { + //factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); + int32 factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL); + if(factionCRC == 0) { + factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); + } + factionCRCList.push_back(make_pair(factionName,factionCRC)); + } + } + //console.addLine("Found factions: " + intToStr(factionCRCList.size())); + lastCheckedCRCTechtreeName = gameSettings->getTech(); + } + + gameSettings->setFactionCRCList(factionCRCList); + gameSettings->setTechCRC(lastCheckedCRCTechtreeValue); + } + } + + if(gameSettings->getMap() != "") { + if(lastCheckedCRCMapName != gameSettings->getMap()) { + Checksum checksum; + string file = Map::getMapPath(gameSettings->getMap(),"",false); + //console.addLine("Checking map CRC [" + file + "]"); + checksum.addFile(file); + lastCheckedCRCMapValue = checksum.getSum(); + lastCheckedCRCMapName = gameSettings->getMap(); + } + gameSettings->setMapCRC(lastCheckedCRCMapValue); + } + } + + //replace server player by network + for(int i= 0; i< gameSettings->getFactionCount(); ++i) { + //replace by network + if(gameSettings->getFactionControl(i)==ctHuman) { + gameSettings->setFactionControl(i, ctNetwork); + } + } + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); +} + void MenuStateConnectedGame::returnToJoinMenu() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -899,6 +1729,8 @@ void MenuStateConnectedGame::mouseMove(int x, int y, const MouseState *ms) { listBoxTileset.mouseMove(x, y); listBoxTechTree.mouseMove(x, y); listBoxPlayerStatus.mouseMove(x,y); + + buttonPlayNow.mouseMove(x, y); } void MenuStateConnectedGame::render() { @@ -1057,6 +1889,8 @@ void MenuStateConnectedGame::render() { renderer.renderListBox(&listBoxEnableSwitchTeamMode); renderer.renderListBox(&listBoxAISwitchTeamAcceptPercent); + renderer.renderButton(&buttonPlayNow); + MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(fileFTPProgressList.empty() == false) { Lang &lang= Lang::getInstance(); @@ -1135,6 +1969,28 @@ void MenuStateConnectedGame::update() { // if(clientInterface != NULL && clientInterface->isConnected()) { + //printf("#2 admin key [%d] client key [%d]\n",settings->getMasterserver_admin(),clientInterface->getSessionKey()); + + listBoxMap.setEditable(isMasterserverAdmin()); + buttonPlayNow.setVisible(isMasterserverAdmin()); + listBoxTechTree.setEditable(isMasterserverAdmin()); + listBoxTileset.setEditable(isMasterserverAdmin()); + listBoxEnableSwitchTeamMode.setEditable(isMasterserverAdmin()); + listBoxAISwitchTeamAcceptPercent.setEditable(isMasterserverAdmin()); + listBoxFogOfWar.setEditable(isMasterserverAdmin()); + listBoxEnableObserverMode.setEditable(isMasterserverAdmin()); + listBoxAllowObservers.setEditable(isMasterserverAdmin()); + listBoxNetworkPauseGameForLaggedClients.setEditable(isMasterserverAdmin()); + + if(isMasterserverAdmin() == true) { + for(unsigned int i = 0; i < GameConstants::maxPlayers; ++i) { + listBoxControls[i].setEditable(isMasterserverAdmin()); + listBoxRMultiplier[i].setEditable(isMasterserverAdmin()); + listBoxFactions[i].setEditable(isMasterserverAdmin()); + listBoxTeams[i].setEditable(isMasterserverAdmin()); + } + } + if(difftime(time(NULL),lastNetworkSendPing) >= GameConstants::networkPingInterval) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to sendPingMessage...\n",__FILE__,__FUNCTION__,__LINE__); @@ -1641,10 +2497,14 @@ void MenuStateConnectedGame::update() { if(getMissingTilesetFromFTPServerInProgress == false && gameSettings->getTileset() != "") { // tileset + tilesets = tilesetFiles; + std::for_each(tilesets.begin(), tilesets.end(), FormatString()); + if(std::find(tilesetFiles.begin(),tilesetFiles.end(),gameSettings->getTileset()) != tilesetFiles.end()) { lastMissingTileSet = ""; getMissingTilesetFromFTPServer = ""; - tilesets.push_back(formatString(gameSettings->getTileset())); + //tilesets.push_back(formatString(gameSettings->getTileset())); + listBoxTileset.setSelectedItem(formatString(gameSettings->getTileset())); } else { // try to get the tileset via ftp @@ -1686,17 +2546,25 @@ void MenuStateConnectedGame::update() { clientInterface->sendTextMessage(szMsg,-1, lang.isLanguageLocal(languageList[i]),languageList[i]); } } + + listBoxTileset.setItems(tilesets); + listBoxTileset.setSelectedItem(ITEM_MISSING); } - listBoxTileset.setItems(tilesets); + } if(getMissingTechtreeFromFTPServerInProgress == false && gameSettings->getTech() != "") { // techtree + techtree = techTreeFiles; + std::for_each(techtree.begin(), techtree.end(), FormatString()); + if(std::find(techTreeFiles.begin(),techTreeFiles.end(),gameSettings->getTech()) != techTreeFiles.end()) { lastMissingTechtree = ""; getMissingTechtreeFromFTPServer = ""; - techtree.push_back(formatString(gameSettings->getTech())); + //techtree.push_back(formatString(gameSettings->getTech())); + reloadFactions(true); + listBoxTechTree.setSelectedItem(formatString(gameSettings->getTech())); } else { // try to get the tileset via ftp @@ -1738,8 +2606,9 @@ void MenuStateConnectedGame::update() { clientInterface->sendTextMessage(szMsg,-1, lang.isLanguageLocal(languageList[i]),languageList[i]); } } + listBoxTechTree.setItems(techtree); + listBoxTechTree.setSelectedItem(ITEM_MISSING); } - listBoxTechTree.setItems(techtree); // techtree //techtree.push_back(formatString(gameSettings->getTech())); @@ -1762,12 +2631,16 @@ void MenuStateConnectedGame::update() { if(getMissingMapFromFTPServerInProgress == false && gameSettings->getMap() != "") { // map - if(currentMap != gameSettings->getMap()) {// load the setup again + maps = formattedMapFiles; + + if(currentMap != gameSettings->getMap()) {// load the setup again currentMap = gameSettings->getMap(); } bool mapLoaded = loadMapInfo(Map::getMapPath(currentMap,"",false), &mapInfo, true); if(mapLoaded == true) { - maps.push_back(formatString(gameSettings->getMap())); + if(find(maps.begin(),maps.end(),formatString(gameSettings->getMap())) == maps.end()) { + maps.push_back(formatString(gameSettings->getMap())); + } } else { // try to get the map via ftp @@ -1784,7 +2657,13 @@ void MenuStateConnectedGame::update() { } maps.push_back(ITEM_MISSING); } + listBoxMap.setItems(maps); + + string mapFile = gameSettings->getMap(); + mapFile = formatString(mapFile); + listBoxMap.setSelectedItem(mapFile); + labelMapInfo.setText(mapInfo.desc); } @@ -1846,8 +2725,11 @@ void MenuStateConnectedGame::update() { // Control for(int i=0; i tilesetFiles; vector factionFiles; + vector playerSortedMaps[GameConstants::maxPlayers+1]; + vector formattedPlayerSortedMaps[GameConstants::maxPlayers+1]; + vector formattedMapFiles; + GraphicMessageBox ftpMessageBox; FTPClientThread *ftpClientThread; FTPMessageType ftpMissingDataType; @@ -174,6 +178,8 @@ private: GraphicLabel labelAISwitchTeamAcceptPercent; GraphicListBox listBoxAISwitchTeamAcceptPercent; + GraphicButton buttonPlayNow; + public: MenuStateConnectedGame(Program *program, MainMenu *mainMenu, JoinMenu joinMenuInfo=jmSimple, bool openNetworkSlots= false); @@ -208,6 +214,14 @@ private: int32 getNetworkPlayerStatus(); void cleanupMapPreviewTexture(); + + void mouseClickAdmin(int x, int y, MouseButton mouseButton); + string getCurrentMapFile(); + void loadGameSettings(GameSettings *gameSettings); + void reloadFactions(bool keepExistingSelectedItem); + void PlayNow(bool saveGame); + bool isMasterserverAdmin(); + void broadCastGameSettingsToMasterserver(); }; }}//end namespace diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index 5484cae08..07c0429c1 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -47,9 +47,17 @@ struct FormatString { // class MenuStateCustomGame // ===================================================== -MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, bool openNetworkSlots,bool parentMenuIsMasterserver, bool autostart, GameSettings *settings) : +MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, + bool openNetworkSlots,bool parentMenuIsMasterserver, bool autostart, + GameSettings *settings, bool masterserverMode) : MenuState(program, mainMenu, "new-game") { + this->masterserverMode = masterserverMode; + this->lastMasterServerSettingsUpdateCount = 0; + this->masterserverModeMinimalResources = true; + + //printf("this->masterserverMode = %d [%d]\n",this->masterserverMode,masterserverMode); + forceWaitForShutdown = true; this->autostart = autostart; this->autoStartSettings = settings; @@ -1374,6 +1382,11 @@ void MenuStateCustomGame::mouseMove(int x, int y, const MouseState *ms){ listBoxAdvanced.mouseMove(x, y); } +bool MenuStateCustomGame::isMasterserverMode() const { + //return (this->masterserverMode == true && this->masterserverModeMinimalResources == true); + return false; +} + void MenuStateCustomGame::render() { try { Renderer &renderer= Renderer::getInstance(); @@ -1521,7 +1534,6 @@ void MenuStateCustomGame::render() { renderer.renderListBox(&listBoxTechTree); renderer.renderListBox(&listBoxAdvanced); - if(listBoxPublishServer.getEditable()) { renderer.renderListBox(&listBoxPublishServer); @@ -1727,6 +1739,22 @@ void MenuStateCustomGame::update() { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + if(this->masterserverMode == true && serverInterface->getGameSettingsUpdateCount() > lastMasterServerSettingsUpdateCount && + serverInterface->getGameSettings() != NULL) { + const GameSettings *settings = serverInterface->getGameSettings(); + + lastMasterServerSettingsUpdateCount = serverInterface->getGameSettingsUpdateCount(); + //printf("#2 custom menu got map [%s]\n",settings->getMap().c_str()); + + setupUIFromGameSettings(*settings); + } + if(this->masterserverMode == true && serverInterface->getMasterserverAdminRequestLaunch() == true) { + safeMutex.ReleaseLock(); + + PlayNow(false); + return; + } + // handle setting changes from clients SwitchSetupRequest ** switchSetupRequests = serverInterface->getSwitchSetupRequests(); //!!! @@ -2042,9 +2070,11 @@ void MenuStateCustomGame::update() { needToPublishDelayed=false; } } - if(!needToPublishDelayed){ + if(needToPublishDelayed == false || masterserverMode == true) { bool broadCastSettings = (difftime(time(NULL),lastSetChangedGameSettings) >= 2); + //printf("broadCastSettings = %d\n",broadCastSettings); + if(broadCastSettings == true) { needToBroadcastServerSettings=true; } @@ -2210,6 +2240,9 @@ void MenuStateCustomGame::simpleTask(BaseThread *callingThread) { std::map newPublishToServerInfo = publishToServerInfo; publishToServerInfo.clear(); bool broadCastSettings = needToBroadcastServerSettings; + + //printf("simpleTask broadCastSettings = %d\n",broadCastSettings); + needToBroadcastServerSettings = false; bool hasClientConnection = false; @@ -2284,6 +2317,9 @@ void MenuStateCustomGame::simpleTask(BaseThread *callingThread) { } if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + //printf("simpleTask broadCastSettings = %d hasClientConnection = %d\n",broadCastSettings,hasClientConnection); + GameSettings gameSettings; loadGameSettings(&gameSettings); @@ -2352,6 +2388,16 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + if(this->masterserverMode == true && serverInterface->getGameSettingsUpdateCount() > lastMasterServerSettingsUpdateCount && + serverInterface->getGameSettings() != NULL) { + const GameSettings *settings = serverInterface->getGameSettings(); + + lastMasterServerSettingsUpdateCount = serverInterface->getGameSettingsUpdateCount(); + //printf("#1 custom menu got map [%s]\n",settings->getMap().c_str()); + + setupUIFromGameSettings(*settings); + } + // Test flags values //gameSettings->setFlagTypes1(ft1_show_map_resources); // @@ -2579,6 +2625,37 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force gameSettings->setMapCRC(lastCheckedCRCMapValue); } } + + //printf("this->masterserverMode = %d\n",this->masterserverMode); + + if(this->masterserverMode == true) { + time_t clientConnectedTime = 0; + + //printf("mapInfo.players [%d]\n",mapInfo.players); + + for(int i= 0; i < mapInfo.players; ++i) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(listBoxControls[i].getSelectedItemIndex() == ctNetwork) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if( serverInterface->getSlot(i) != NULL && serverInterface->getSlot(i)->isConnected()) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + //printf("slot = %d serverInterface->getSlot(i)->getConnectedTime() = %d\n",i,serverInterface->getSlot(i)->getConnectedTime()); + + if(clientConnectedTime == 0 || serverInterface->getSlot(i)->getConnectedTime() < clientConnectedTime) { + clientConnectedTime = serverInterface->getSlot(i)->getConnectedTime(); + gameSettings->setMasterserver_admin(serverInterface->getSlot(i)->getSessionKey()); + + //printf("slot = %d, admin key [%d]\n",i,gameSettings->getMasterserver_admin()); + } + } + } + } + + } + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); } @@ -2750,7 +2827,7 @@ void MenuStateCustomGame::setupUIFromGameSettings(const GameSettings &gameSettin listBoxMapFilter.setSelectedItemIndex(gameSettings.getMapFilterIndex()); listBoxMap.setItems(formattedPlayerSortedMaps[gameSettings.getMapFilterIndex()]); - printf("In [%s::%s line %d] map [%s]\n",__FILE__,__FUNCTION__,__LINE__,gameSettings.getMap().c_str()); + //printf("In [%s::%s line %d] map [%s]\n",__FILE__,__FUNCTION__,__LINE__,gameSettings.getMap().c_str()); string mapFile = gameSettings.getMap(); mapFile = formatString(mapFile); diff --git a/source/glest_game/menu/menu_state_custom_game.h b/source/glest_game/menu/menu_state_custom_game.h index 5ad7bcbd7..6eb26eb31 100644 --- a/source/glest_game/menu/menu_state_custom_game.h +++ b/source/glest_game/menu/menu_state_custom_game.h @@ -167,9 +167,14 @@ private: vector > factionCRCList; bool forceWaitForShutdown; + bool masterserverMode; + bool masterserverModeMinimalResources; + int lastMasterServerSettingsUpdateCount; public: - MenuStateCustomGame(Program *program, MainMenu *mainMenu ,bool openNetworkSlots= false, bool parentMenuIsMasterserver=false, bool autostart=false,GameSettings *settings=NULL); + MenuStateCustomGame(Program *program, MainMenu *mainMenu , + bool openNetworkSlots= false, bool parentMenuIsMasterserver=false, + bool autostart=false,GameSettings *settings=NULL,bool masterserverMode=false); virtual ~MenuStateCustomGame(); void mouseClick(int x, int y, MouseButton mouseButton); @@ -184,6 +189,7 @@ public: virtual void simpleTask(BaseThread *callingThread); virtual bool isInSpecialKeyCaptureEvent(); + virtual bool isMasterserverMode() const; private: diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index e6007e931..512b5c0e0 100644 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -1247,4 +1247,30 @@ string ClientInterface::getHumanPlayerName(int index) { return result; } + +void ClientInterface::setGameSettings(GameSettings *serverGameSettings) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__); + //MutexSafeWrapper safeMutex(&serverSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + gameSettings = *serverGameSettings; + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__); +} + +void ClientInterface::broadcastGameSetup(const GameSettings *gameSettings) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + //MutexSafeWrapper safeMutex(&serverSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtBroadCastSetup); + //broadcastMessage(&networkMessageLaunch); + sendMessage(&networkMessageLaunch); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); +} + +void ClientInterface::broadcastGameStart(const GameSettings *gameSettings) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + //MutexSafeWrapper safeMutex(&serverSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtLaunch); + //broadcastMessage(&networkMessageLaunch); + sendMessage(&networkMessageLaunch); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); +} + }}//end namespace diff --git a/source/glest_game/network/client_interface.h b/source/glest_game/network/client_interface.h index a62147003..3eddbf350 100644 --- a/source/glest_game/network/client_interface.h +++ b/source/glest_game/network/client_interface.h @@ -28,7 +28,7 @@ namespace Glest{ namespace Game{ // class ClientInterface // ===================================================== -class ClientInterface: public GameNetworkInterface{ +class ClientInterface: public GameNetworkInterface { private: static const int messageWaitTimeout; static const int waitSleepTime; @@ -109,6 +109,12 @@ public: virtual int getHumanPlayerIndex() const {return playerIndex;} int getServerFTPPort() const { return serverFTPPort; } + int getSessionKey() const { return sessionKey; } + + void setGameSettings(GameSettings *serverGameSettings); + void broadcastGameSetup(const GameSettings *gameSettings); + void broadcastGameStart(const GameSettings *gameSettings); + protected: Mutex * getServerSynchAccessor() { return NULL; } diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index 315f9cfff..6ac15943e 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -555,6 +555,51 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { } break; + case nmtLaunch: + case nmtBroadCastSetup: + { + if(this->serverInterface->getGameSettings() == NULL || + sessionKey != this->serverInterface->getGameSettings()->getMasterserver_admin()) { + string playerNameStr = name; + string sErr = "Client has invalid admin sessionid for player [" + playerNameStr + "]"; + printf("%s\n",sErr.c_str()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str()); + + close(); + return; + } + + NetworkMessageLaunch networkMessageLaunch; + if(receiveMessage(&networkMessageLaunch)) { + if(networkMessageLaunch.getMessageType() == nmtLaunch) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtLaunch\n",__FILE__,__FUNCTION__,__LINE__); + } + else if(networkMessageLaunch.getMessageType() == nmtBroadCastSetup) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtBroadCastSetup\n",__FILE__,__FUNCTION__,__LINE__); + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); + + char szBuf[1024]=""; + snprintf(szBuf,1023,"In [%s::%s Line: %d] Invalid networkMessageLaunch.getMessageType() = %d",__FILE__,__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); + throw runtime_error(szBuf); + } + + GameSettings gameSettings; + networkMessageLaunch.buildGameSettings(&gameSettings); + + //printf("Connection slot got networkMessageLaunch.getMessageType() = %d, got map [%s]\n",networkMessageLaunch.getMessageType(),gameSettings.getMap().c_str()); + + this->serverInterface->setGameSettings(&gameSettings,false); + this->serverInterface->broadcastGameSetup(&gameSettings); + + if(networkMessageLaunch.getMessageType() == nmtLaunch) { + this->serverInterface->setMasterserverAdminRequestLaunch(true); + } + } + } + break; + //process datasynch messages case nmtSynchNetworkGameDataStatus: { diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index 664ec451f..9cd1b7e82 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -183,6 +183,9 @@ public: string getNetworkPlayerLanguage() const { return playerLanguage; } + time_t getConnectedTime() const { return connectedTime; } + int getSessionKey() const { return sessionKey; } + protected: Mutex * getServerSynchAccessor(); diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index 137ddfe1a..2fe761935 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -231,6 +231,7 @@ NetworkMessageLaunch::NetworkMessageLaunch() { data.factionCRCList[i] = 0; } data.aiAcceptSwitchTeamPercentChance = 0; + data.masterserver_admin = -1; } NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8 messageType) { @@ -281,6 +282,7 @@ NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8 } data.aiAcceptSwitchTeamPercentChance = gameSettings->getAiAcceptSwitchTeamPercentChance(); + data.masterserver_admin = gameSettings->getMasterserver_admin(); } void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const { @@ -327,6 +329,7 @@ void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const { } gameSettings->setAiAcceptSwitchTeamPercentChance(data.aiAcceptSwitchTeamPercentChance); + gameSettings->setMasterserver_admin(data.masterserver_admin); } vector > NetworkMessageLaunch::getFactionCRCList() const { diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index 3f7417e70..daa2c6a0d 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -234,6 +234,7 @@ private: uint32 flagTypes1; int8 aiAcceptSwitchTeamPercentChance; + int32 masterserver_admin; }; private: diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 90f898c9d..7491b486d 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -57,6 +57,7 @@ ServerInterface::ServerInterface(bool publishEnabled) :GameNetworkInterface() { ftpServer = NULL; inBroadcastMessage = false; lastGlobalLagCheckTime = 0; + masterserverAdminRequestLaunch = false; maxFrameCountLagAllowed = Config::getInstance().getInt("MaxFrameCountLagAllowed", intToStr(maxFrameCountLagAllowed).c_str()); maxFrameCountLagAllowedEver = Config::getInstance().getInt("MaxFrameCountLagAllowedEver", intToStr(maxFrameCountLagAllowedEver).c_str()); @@ -1696,8 +1697,8 @@ void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool wai } } - gameSettingsUpdateCount++; } + gameSettingsUpdateCount++; if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__); } diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index 191b9d5d7..41bba9452 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -79,6 +79,8 @@ private: Mutex inBroadcastMessageThreadAccessor; bool inBroadcastMessage; + bool masterserverAdminRequestLaunch; + public: ServerInterface(bool publishEnabled); virtual ~ServerInterface(); @@ -118,6 +120,12 @@ public: bool launchGame(const GameSettings *gameSettings); void setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck); void broadcastGameSetup(const GameSettings *gameSettings); + + int getGameSettingsUpdateCount() const { return gameSettingsUpdateCount; } + + bool getMasterserverAdminRequestLaunch() const { return masterserverAdminRequestLaunch; } + void setMasterserverAdminRequestLaunch(bool value) { masterserverAdminRequestLaunch = value; } + void updateListen(); virtual bool getConnectHasHandshaked() const { @@ -183,6 +191,7 @@ private: int64 getNextEventId(); void processTextMessageQueue(); void processBroadCastMessageQueue(); + protected: void signalClientsToRecieveData(std::map & socketTriggeredList, std::map & eventList, std::map & mapSlotSignalledList); void checkForCompletedClients(std::map & mapSlotSignalledList,std::vector &errorMsgList,std::map &eventList);