diff --git a/source/glest_game/game/game_settings.h b/source/glest_game/game/game_settings.h index 2008ce30..602f71a6 100644 --- a/source/glest_game/game/game_settings.h +++ b/source/glest_game/game/game_settings.h @@ -44,6 +44,7 @@ private: string scenarioDir; string factionTypeNames[GameConstants::maxPlayers]; //faction names string networkPlayerNames[GameConstants::maxPlayers]; + int networkPlayerStatuses[GameConstants::maxPlayers]; ControlType factionControls[GameConstants::maxPlayers]; int resourceMultiplierIndex[GameConstants::maxPlayers]; @@ -88,6 +89,7 @@ public: for(int i = 0; i < GameConstants::maxPlayers; ++i) { factionTypeNames[i] = ""; networkPlayerNames[i] = ""; + networkPlayerStatuses[i] = 0; factionControls[i] = ctClosed; resourceMultiplierIndex[i] = 1.0f; teams[i] = 0; @@ -112,6 +114,8 @@ public: const string &getScenarioDir() const {return scenarioDir;} const string &getFactionTypeName(int factionIndex) const {return factionTypeNames[factionIndex];} const string &getNetworkPlayerName(int factionIndex) const {return networkPlayerNames[factionIndex];} + const int getNetworkPlayerStatuses(int factionIndex) const { return networkPlayerStatuses[factionIndex];} + const string getNetworkPlayerNameByPlayerIndex(int playerIndex) const { string result = ""; for(int i = 0; i < GameConstants::maxPlayers; ++i) { @@ -168,8 +172,9 @@ public: void setFactionTypeName(int factionIndex, const string& factionTypeName) {this->factionTypeNames[factionIndex]= factionTypeName;} void setNetworkPlayerName(int factionIndex,const string& playername) {this->networkPlayerNames[factionIndex]= playername;} + void setNetworkPlayerStatuses(int factionIndex,int status) {this->networkPlayerStatuses[factionIndex]= status;} void setFactionControl(int factionIndex, ControlType controller) {this->factionControls[factionIndex]= controller;} - void setResourceMultiplierIndex(int factionIndex, int multiplierIndex) {this->resourceMultiplierIndex[factionIndex]= multiplierIndex;} + void setResourceMultiplierIndex(int factionIndex, int multiplierIndex) {this->resourceMultiplierIndex[factionIndex]= multiplierIndex;} void setThisFactionIndex(int thisFactionIndex) {this->thisFactionIndex= thisFactionIndex;} void setFactionCount(int factionCount) {this->factionCount= factionCount;} diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 3b22cf8d..65b21787 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -102,7 +102,7 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM enableFactionTexturePreview = config.getBool("FactionPreview","true"); enableMapPreview = config.getBool("MapPreview","true"); - vector teamItems, controlItems, results, rMultiplier; + vector teamItems, controlItems, results, rMultiplier, playerStatuses; int setupPos=590; int mapHeadPos=330; int mapPos=mapHeadPos-30; @@ -272,11 +272,21 @@ MenuStateConnectedGame::MenuStateConnectedGame(Program *program, MainMenu *mainM labelTechTree.setText(lang.get("TechTree")); + listBoxPlayerStatus.registerGraphicComponent(containerName,"listBoxPlayerStatus"); + listBoxPlayerStatus.init(10, 600, 150); + playerStatuses.push_back(lang.get("PlayerStatusSetup")); + playerStatuses.push_back(lang.get("PlayerStatusBeRightBack")); + playerStatuses.push_back(lang.get("PlayerStatusReady")); + listBoxPlayerStatus.setItems(playerStatuses); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); //list boxes xoffset=100; int rowHeight=27; for(int i=0; iisConnected()) { clientInterface->setGameSettingsReceived(false); - clientInterface->sendSwitchSetupRequest(listBoxFactions[i].getSelectedItem(),i,-1,listBoxTeams[i].getSelectedItemIndex(),getHumanPlayerName(),switchSetupRequestFlagType); + clientInterface->sendSwitchSetupRequest( + listBoxFactions[i].getSelectedItem(),i,-1, + listBoxTeams[i].getSelectedItemIndex(), + getHumanPlayerName(), + getNetworkPlayerStatus(), + switchSetupRequestFlagType); switchSetupRequestFlagType=ssrft_None; } break; @@ -587,7 +604,12 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ soundRenderer.playFx(coreData.getClickSoundA()); if(clientInterface->isConnected()) { clientInterface->setGameSettingsReceived(false); - clientInterface->sendSwitchSetupRequest(listBoxFactions[i].getSelectedItem(),i,-1,listBoxTeams[i].getSelectedItemIndex(),getHumanPlayerName(),switchSetupRequestFlagType); + clientInterface->sendSwitchSetupRequest( + listBoxFactions[i].getSelectedItem(),i,-1, + listBoxTeams[i].getSelectedItemIndex(), + getHumanPlayerName(), + getNetworkPlayerStatus(), + switchSetupRequestFlagType); switchSetupRequestFlagType=ssrft_None; } break; @@ -600,7 +622,13 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ clientInterface->setGameSettingsReceived(false); settingsReceivedFromServer=false; SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] sending a switchSlot request from %d to %d\n",__FILE__,__FUNCTION__,__LINE__,clientInterface->getGameSettings()->getThisFactionIndex(),i); - clientInterface->sendSwitchSetupRequest(listBoxFactions[myCurrentIndex].getSelectedItem(),myCurrentIndex,i,listBoxTeams[myCurrentIndex].getSelectedItemIndex(),labelPlayerNames[myCurrentIndex].getText(),switchSetupRequestFlagType); + clientInterface->sendSwitchSetupRequest( + listBoxFactions[myCurrentIndex].getSelectedItem(), + myCurrentIndex,i, + listBoxTeams[myCurrentIndex].getSelectedItemIndex(), + labelPlayerNames[myCurrentIndex].getText(), + getNetworkPlayerStatus(), + switchSetupRequestFlagType); labelPlayerNames[myCurrentIndex].setText(""); labelPlayerNames[i].setText(""); switchSetupRequestFlagType=ssrft_None; @@ -615,6 +643,25 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){ } } } + + if(listBoxPlayerStatus.mouseClick(x,y)) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + soundRenderer.playFx(coreData.getClickSoundC()); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + + ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface(); + if(clientInterface->isConnected()) { + clientInterface->setGameSettingsReceived(false); + clientInterface->sendSwitchSetupRequest( + listBoxFactions[clientInterface->getPlayerIndex()].getSelectedItem(), + clientInterface->getPlayerIndex(),-1, + listBoxTeams[clientInterface->getPlayerIndex()].getSelectedItemIndex(), + getHumanPlayerName(), + getNetworkPlayerStatus(), + switchSetupRequestFlagType); + switchSetupRequestFlagType=ssrft_None; + } + } } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); } @@ -707,9 +754,6 @@ void MenuStateConnectedGame::render() { // START - this code ensure player title and player names don't overlap int offsetPosition=0; for(int i=0; i < GameConstants::maxPlayers; ++i) { - //labelPlayers[i].registerGraphicComponent(containerName,"labelPlayers" + intToStr(i)); - //labelPlayers[i].init(xoffset+50, setupPos-30-i*rowHeight); - const Metrics &metrics= Metrics::getInstance(); const FontMetrics *fontMetrics= CoreData::getInstance().getMenuFontNormal()->getMetrics(); if(fontMetrics == NULL) { @@ -726,7 +770,11 @@ void MenuStateConnectedGame::render() { } // END + renderer.renderListBox(&listBoxPlayerStatus); + for(int i = 0; i < GameConstants::maxPlayers; ++i) { + renderer.renderLabel(&labelPlayerStatus[i]); + if(crcPlayerTextureCache[i] != NULL) { // Render the player # label the player's color Vec3f playerColor = crcPlayerTextureCache[i]->getPixmap()->getPixel3f(0, 0); @@ -936,7 +984,7 @@ void MenuStateConnectedGame::update() { (tilesetCRC != 0 && tilesetCRC != gameSettings->getTilesetCRC()) || (techCRC != 0 && techCRC != gameSettings->getTechCRC())); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nmapCRC [%d] gameSettings->getMapCRC() [%d]\ntilesetCRC [%d] gameSettings->getTilesetCRC() [%d]\ntechCRC [%d] gameSettings->getTechCRC() [%d]\n",mapCRC,gameSettings->getMapCRC(),tilesetCRC,gameSettings->getTilesetCRC(),techCRC,gameSettings->getTechCRC()); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nmapCRC [%d] gameSettings->getMapCRC() [%d]\ntilesetCRC [%d] gameSettings->getTilesetCRC() [%d]\ntechCRC [%d] gameSettings->getTechCRC() [%d]\n",mapCRC,gameSettings->getMapCRC(),tilesetCRC,gameSettings->getTilesetCRC(),techCRC,gameSettings->getTechCRC()); if(dataSynchMismatch == true) { string labelSynch = lang.get("DataNotSynchedTitle"); @@ -1349,6 +1397,8 @@ void MenuStateConnectedGame::update() { listBoxControls[i].setSelectedItemIndex(ctClosed); listBoxFactions[i].setEditable(false); listBoxTeams[i].setEditable(false); + + labelPlayerStatus[i].setText(""); } //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -1357,18 +1407,39 @@ void MenuStateConnectedGame::update() { //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] errorOnMissingData = %d\n",__FILE__,__FUNCTION__,__LINE__,errorOnMissingData); for(int i=0; igetFactionCount(); ++i){ - int slot=gameSettings->getStartLocationIndex(i); + int slot = gameSettings->getStartLocationIndex(i); + + if(gameSettings != NULL) { + if( gameSettings->getFactionControl(i) == ctNetwork || + gameSettings->getFactionControl(i) == ctHuman) { + switch(gameSettings->getNetworkPlayerStatuses(i)) { + case npst_BeRightBack: + labelPlayerStatus[slot].setText(lang.get("PlayerStatusBeRightBack")); + break; + case npst_Ready: + labelPlayerStatus[slot].setText(lang.get("PlayerStatusReady")); + break; + case npst_PickSettings: + labelPlayerStatus[slot].setText(lang.get("PlayerStatusSetup")); + break; + default: + labelPlayerStatus[slot].setText(""); + break; + } + } + } + + listBoxControls[slot].setSelectedItemIndex(gameSettings->getFactionControl(i),errorOnMissingData); listBoxRMultiplier[slot].setSelectedItemIndex((gameSettings->getResourceMultiplierIndex(i))); listBoxTeams[slot].setSelectedItemIndex(gameSettings->getTeam(i),errorOnMissingData); //listBoxFactions[slot].setSelectedItem(formatString(gameSettings->getFactionTypeName(i)),errorOnMissingData); listBoxFactions[slot].setSelectedItem(formatString(gameSettings->getFactionTypeName(i)),false); - if(gameSettings->getFactionControl(i) == ctNetwork ){ labelNetStatus[slot].setText(gameSettings->getNetworkPlayerName(i)); - if(gameSettings->getThisFactionIndex() != i && - gameSettings->getNetworkPlayerName(i) != "" && - gameSettings->getNetworkPlayerName(i) != GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { + if( gameSettings->getThisFactionIndex() != i && + gameSettings->getNetworkPlayerName(i) != "" && + gameSettings->getNetworkPlayerName(i) != GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { labelPlayerNames[slot].setText(gameSettings->getNetworkPlayerName(i)); } } @@ -1450,7 +1521,11 @@ void MenuStateConnectedGame::update() { clientInterface->getIntroDone() == true && (switchSetupRequestFlagType & ssrft_NetworkPlayerName) == ssrft_NetworkPlayerName) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] getHumanPlayerName() = [%s], clientInterface->getGameSettings()->getThisFactionIndex() = %d\n",__FILE__,__FUNCTION__,__LINE__,getHumanPlayerName().c_str(),clientInterface->getGameSettings()->getThisFactionIndex()); - clientInterface->sendSwitchSetupRequest("",clientInterface->getPlayerIndex(),-1,-1,getHumanPlayerName(),switchSetupRequestFlagType); + clientInterface->sendSwitchSetupRequest("", + clientInterface->getPlayerIndex(),-1,-1, + getHumanPlayerName(), + getNetworkPlayerStatus(), + switchSetupRequestFlagType); switchSetupRequestFlagType=ssrft_None; } @@ -1884,6 +1959,23 @@ void MenuStateConnectedGame::showFTPMessageBox(const string &text, const string } } +int32 MenuStateConnectedGame::getNetworkPlayerStatus() { + int32 result = npst_None; + switch(listBoxPlayerStatus.getSelectedItemIndex()) { + case 2: + result = npst_Ready; + break; + case 1: + result = npst_BeRightBack; + break; + case 0: + result = npst_PickSettings; + break; + } + + return result; +} + void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result, void *userdata) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); diff --git a/source/glest_game/menu/menu_state_connected_game.h b/source/glest_game/menu/menu_state_connected_game.h index 8930ff78..67228464 100644 --- a/source/glest_game/menu/menu_state_connected_game.h +++ b/source/glest_game/menu/menu_state_connected_game.h @@ -87,6 +87,9 @@ private: GraphicLabel labelNetStatus[GameConstants::maxPlayers]; GraphicButton grabSlotButton[GameConstants::maxPlayers]; + GraphicListBox listBoxPlayerStatus; + GraphicLabel labelPlayerStatus[GameConstants::maxPlayers]; + GraphicLabel labelAllowObservers; GraphicListBox listBoxAllowObservers; @@ -187,6 +190,8 @@ private: void showFTPMessageBox(const string &text, const string &header, bool toggle); virtual void FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result,void *userdata); + + int32 getNetworkPlayerStatus(); }; }}//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 a3b002f3..43a697c6 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -360,6 +360,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b xoffset=100; int rowHeight=27; for(int i=0; i playerStatuses; + playerStatuses.push_back(lang.get("PlayerStatusSetup")); + playerStatuses.push_back(lang.get("PlayerStatusBeRightBack")); + playerStatuses.push_back(lang.get("PlayerStatusReady")); + listBoxPlayerStatus.setItems(playerStatuses); + // write hint to console: Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); @@ -664,8 +677,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){ needToRepublishToMasterserver = true; } - if(hasNetworkGameSettings() == true) - { + if(hasNetworkGameSettings() == true) { //delay publishing for 5 seconds needToPublishDelayed=true; mapPublishingDelayTimer=time(NULL); @@ -679,8 +691,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){ needToRepublishToMasterserver = true; } - if(hasNetworkGameSettings() == true) - { + if(hasNetworkGameSettings() == true) { needToSetChangedGameSettings = true; lastSetChangedGameSettings = time(NULL); } @@ -830,9 +841,6 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){ //no human if(humanIndex1 == -1 && humanIndex2 == -1) { listBoxControls[i].setSelectedItemIndex(ctHuman); - //labelPlayerNames[i].setText(""); - //labelPlayerNames[i].setText(getHumanPlayerName()); - 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 @@ -845,8 +853,6 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){ 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[closeSlotIndex].setText(""); - labelPlayerNames[humanSlotIndex].setText((origPlayName != "" ? origPlayName : getHumanPlayerName())); } updateNetworkSlots(); @@ -910,6 +916,21 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){ } } } + + if(hasNetworkGameSettings() == true && listBoxPlayerStatus.mouseClick(x,y)) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + soundRenderer.playFx(coreData.getClickSoundC()); + 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]=""; @@ -1225,9 +1246,6 @@ void MenuStateCustomGame::render() { // START - this code ensure player title and player names don't overlap int offsetPosition=0; for(int i=0; i < GameConstants::maxPlayers; ++i) { - //labelPlayers[i].registerGraphicComponent(containerName,"labelPlayers" + intToStr(i)); - //labelPlayers[i].init(xoffset+50, setupPos-30-i*rowHeight); - const Metrics &metrics= Metrics::getInstance(); const FontMetrics *fontMetrics= CoreData::getInstance().getMenuFontNormal()->getMetrics(); if(fontMetrics == NULL) { @@ -1244,7 +1262,15 @@ void MenuStateCustomGame::render() { } // END + if(hasNetworkGameSettings() == true) { + renderer.renderListBox(&listBoxPlayerStatus); + } + for(int i = 0; i < GameConstants::maxPlayers; ++i) { + if(hasNetworkGameSettings() == true) { + renderer.renderLabel(&labelPlayerStatus[i]); + } + if(crcPlayerTextureCache[i] != NULL) { // Render the player # label the player's color Vec3f playerColor = crcPlayerTextureCache[i]->getPixmap()->getPixel3f(0, 0); @@ -1446,14 +1472,6 @@ void MenuStateCustomGame::update() { if(switchSetupRequests[i]->getToFactionIndex() != -1) { int newFactionIdx = switchSetupRequests[i]->getToFactionIndex(); - /* - if(switchSetupRequests[i]->getNetworkPlayerName() != GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { - labelPlayerNames[k].setText(switchSetupRequests[i]->getNetworkPlayerName()); - } - else { - labelPlayerNames[k].setText(""); - } - */ //printf("switchSlot request from %d to %d\n",switchSetupRequests[i]->getCurrentFactionIndex(),switchSetupRequests[i]->getToFactionIndex()); int switchFactionIdx = switchSetupRequests[i]->getCurrentFactionIndex(); @@ -1515,18 +1533,58 @@ void MenuStateCustomGame::update() { //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] mapInfo.players = %d\n",__FILE__,__FUNCTION__,__LINE__,mapInfo.players); + GameSettings gameSettings; + loadGameSettings(&gameSettings); + for(int i= 0; i< mapInfo.players; ++i) { //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(hasNetworkGameSettings() == true) { + if(listBoxControls[i].getSelectedItemIndex() == ctHuman) { + switch(gameSettings.getNetworkPlayerStatuses(i)) { + case npst_BeRightBack: + labelPlayerStatus[i].setText(lang.get("PlayerStatusBeRightBack")); + break; + case npst_Ready: + labelPlayerStatus[i].setText(lang.get("PlayerStatusReady")); + break; + case npst_PickSettings: + labelPlayerStatus[i].setText(lang.get("PlayerStatusSetup")); + break; + default: + labelPlayerStatus[i].setText(""); + break; + } + } + else { + labelPlayerStatus[i].setText(""); + } + } + if(listBoxControls[i].getSelectedItemIndex() == ctNetwork) { //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); - hasOneNetworkSlotOpen=true; //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] A - ctNetwork\n",__FILE__,__FUNCTION__); if(serverInterface->getSlot(i) != NULL && serverInterface->getSlot(i)->isConnected()) { + + if(hasNetworkGameSettings() == true) { + switch(serverInterface->getSlot(i)->getNetworkPlayerStatus()) { + case npst_BeRightBack: + labelPlayerStatus[i].setText(lang.get("PlayerStatusBeRightBack")); + break; + case npst_Ready: + labelPlayerStatus[i].setText(lang.get("PlayerStatusReady")); + break; + case npst_PickSettings: + default: + labelPlayerStatus[i].setText(lang.get("PlayerStatusSetup")); + break; + } + } + serverInterface->getSlot(i)->setName(labelPlayerNames[i].getText()); //printf("FYI we have at least 1 client connected, slot = %d'\n",i); @@ -1653,9 +1711,6 @@ void MenuStateCustomGame::update() { needToSetChangedGameSettings == true && difftime(time(NULL),lastSetChangedGameSettings) >= 2); - GameSettings gameSettings; - loadGameSettings(&gameSettings); - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); if(chrono.getMillis() > 0) chrono.start(); @@ -2063,10 +2118,8 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) { 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->setNetworkPlayerName(slotIndex, getHumanPlayerName(i)); - //labelPlayerNames[i].setText(getHumanPlayerName(i)); - //SetActivePlayerNameEditor(); + gameSettings->setNetworkPlayerStatuses(slotIndex, getNetworkPlayerStatus()); } gameSettings->setResourceMultiplierIndex(slotIndex, listBoxRMultiplier[i].getSelectedItemIndex()); 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()); @@ -2097,6 +2150,9 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) { if(listBoxControls[i].getSelectedItemIndex() == ctNetwork) { if(serverInterface->getSlot(i) != NULL && serverInterface->getSlot(i)->isConnected()) { + + gameSettings->setNetworkPlayerStatuses(slotIndex,serverInterface->getSlot(i)->getNetworkPlayerStatus()); + 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()); @@ -2121,6 +2177,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) { } else { //gameSettings->setNetworkPlayerName(""); + gameSettings->setNetworkPlayerStatuses(factionCount, 0); labelPlayerNames[i].setText(""); } } @@ -2422,10 +2479,8 @@ bool MenuStateCustomGame::hasNetworkGameSettings() { for(int i=0; i(listBoxControls[i].getSelectedItemIndex()); - if(ct != ctClosed) - { - if(ct == ctNetwork) - { + if(ct != ctClosed) { + if(ct == ctNetwork) { hasNetworkSlot = true; break; } @@ -2898,4 +2953,22 @@ void MenuStateCustomGame::cleanupMapPreviewTexture() { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } +int32 MenuStateCustomGame::getNetworkPlayerStatus() { + int32 result = npst_None; + switch(listBoxPlayerStatus.getSelectedItemIndex()) { + case 2: + result = npst_Ready; + break; + case 1: + result = npst_BeRightBack; + break; + case 0: + default: + result = npst_PickSettings; + break; + } + + return result; +} + }}//end namespace diff --git a/source/glest_game/menu/menu_state_custom_game.h b/source/glest_game/menu/menu_state_custom_game.h index da541e39..af7ead66 100644 --- a/source/glest_game/menu/menu_state_custom_game.h +++ b/source/glest_game/menu/menu_state_custom_game.h @@ -93,6 +93,9 @@ private: GraphicLabel *activeInputLabel; + GraphicLabel labelPlayerStatus[GameConstants::maxPlayers]; + GraphicListBox listBoxPlayerStatus; + bool needToSetChangedGameSettings; time_t lastSetChangedGameSettings; time_t lastMasterserverPublishing; @@ -193,6 +196,8 @@ private: void SetActivePlayerNameEditor(); void cleanup(); + + int32 getNetworkPlayerStatus(); }; }}//end namespace diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index 04dfeb44..2a28ae92 100755 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -932,10 +932,12 @@ void ClientInterface::stopServerDiscovery() { void ClientInterface::sendSwitchSetupRequest(string selectedFactionName, int8 currentFactionIndex, int8 toFactionIndex,int8 toTeam, string networkPlayerName, - int8 flags) { + int8 networkPlayerStatus, int8 flags) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] networkPlayerName [%s] flags = %d\n",__FILE__,__FUNCTION__,__LINE__,networkPlayerName.c_str(),flags); //printf("string-cuf-tof-team= %s-%d-%d-%d\n",selectedFactionName.c_str(),currentFactionIndex,toFactionIndex,toTeam); - SwitchSetupRequest message=SwitchSetupRequest(selectedFactionName, currentFactionIndex, toFactionIndex,toTeam,networkPlayerName, flags); + SwitchSetupRequest message=SwitchSetupRequest(selectedFactionName, + currentFactionIndex, toFactionIndex,toTeam,networkPlayerName, + networkPlayerStatus, flags); sendMessage(&message); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } diff --git a/source/glest_game/network/client_interface.h b/source/glest_game/network/client_interface.h index be44c1c0..ee6133df 100644 --- a/source/glest_game/network/client_interface.h +++ b/source/glest_game/network/client_interface.h @@ -94,7 +94,7 @@ public: void sendSwitchSetupRequest(string selectedFactionName, int8 currentFactionIndex, int8 toFactionIndex, int8 toTeam,string networkPlayerName, - int8 flags); + int8 networkPlayerStatus, int8 flags); virtual bool getConnectHasHandshaked() const { return gotIntro; } std::string getServerIpAddress(); diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index ee84f0be..c23454fb 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -245,6 +245,7 @@ ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex this->sessionKey = 0; this->serverInterface = serverInterface; this->playerIndex = playerIndex; + this->playerStatus = 0; this->currentFrameCount = 0; this->currentLagCount = 0; this->gotLagCountWarning = false; @@ -334,6 +335,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { this->connectedTime = time(NULL); this->clearChatInfo(); this->name = ""; + this->playerStatus = npst_PickSettings; this->ready = false; this->vctFileList.clear(); this->receivedNetworkGameStatus = false; @@ -745,7 +747,9 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { } *(serverInterface->getSwitchSetupRequests()[factionIdx]) = switchSetupRequest; - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] factionIdx = %d, switchSetupRequest.getNetworkPlayerName() [%s] switchSetupRequest.getSwitchFlags() = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdx,switchSetupRequest.getNetworkPlayerName().c_str(),switchSetupRequest.getSwitchFlags()); + this->playerStatus = switchSetupRequest.getNetworkPlayerStatus(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] factionIdx = %d, switchSetupRequest.getNetworkPlayerName() [%s] switchSetupRequest.getNetworkPlayerStatus() = %d, switchSetupRequest.getSwitchFlags() = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdx,switchSetupRequest.getNetworkPlayerName().c_str(),switchSetupRequest.getNetworkPlayerStatus(),switchSetupRequest.getSwitchFlags()); } } break; diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index 2a86e10c..1d7c5dd8 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -122,6 +122,7 @@ private: string versionString; int sessionKey; uint32 connectedRemoteIPAddress; + int playerStatus; public: ConnectionSlot(ServerInterface* serverInterface, int playerIndex); @@ -175,6 +176,8 @@ public: virtual string getHumanPlayerName(int index=-1); virtual int getHumanPlayerIndex() const {return playerIndex;} + int getNetworkPlayerStatus() const { return playerStatus;} + protected: Mutex * getServerSynchAccessor(); diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index bff3ba77..3cdc35e3 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -232,6 +232,7 @@ NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8 for(int i= 0; igetFactionTypeName(i); data.networkPlayerNames[i]= gameSettings->getNetworkPlayerName(i); + data.networkPlayerStatuses[i] = gameSettings->getNetworkPlayerStatuses(i); data.factionControls[i]= gameSettings->getFactionControl(i); data.resourceMultiplierIndex[i]= gameSettings->getResourceMultiplierIndex(i); data.teams[i]= gameSettings->getTeam(i); @@ -266,6 +267,7 @@ void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const { for(int i= 0; isetFactionTypeName(i, data.factionTypeNames[i].getString()); gameSettings->setNetworkPlayerName(i,data.networkPlayerNames[i].getString()); + gameSettings->setNetworkPlayerStatuses(i, data.networkPlayerStatuses[i]); gameSettings->setFactionControl(i, static_cast(data.factionControls[i])); gameSettings->setResourceMultiplierIndex(i,data.resourceMultiplierIndex[i]); gameSettings->setTeam(i, data.teams[i]); @@ -933,18 +935,20 @@ SwitchSetupRequest::SwitchSetupRequest() { data.toFactionIndex=-1; data.toTeam = -1; data.networkPlayerName=""; + data.networkPlayerStatus = npst_None; data.switchFlags = ssrft_None; } SwitchSetupRequest::SwitchSetupRequest(string selectedFactionName, int8 currentFactionIndex, int8 toFactionIndex,int8 toTeam,string networkPlayerName, - int8 flags) { + int8 networkPlayerStatus, int8 flags) { data.messageType= nmtSwitchSetupRequest; data.selectedFactionName=selectedFactionName; data.currentFactionIndex=currentFactionIndex; data.toFactionIndex=toFactionIndex; data.toTeam = toTeam; data.networkPlayerName=networkPlayerName; + data.networkPlayerStatus=networkPlayerStatus; data.switchFlags = flags; } diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index 4f3bb6ef..fcfd799d 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -197,6 +197,7 @@ private: NetworkString tech; NetworkString factionTypeNames[GameConstants::maxPlayers]; //faction names NetworkString networkPlayerNames[GameConstants::maxPlayers]; //networkPlayerNames + int32 networkPlayerStatuses[GameConstants::maxPlayers]; //networkPlayerStatuses int32 mapCRC; int32 tilesetCRC; int32 techCRC; @@ -573,7 +574,15 @@ enum SwitchSetupRequestFlagType { ssrft_CurrentFactionIndex = 0x02, ssrft_ToFactionIndex = 0x04, ssrft_ToTeam = 0x08, - ssrft_NetworkPlayerName = 0x10 + ssrft_NetworkPlayerName = 0x10, + ssrft_PlayerStatus = 0x20 +}; + +enum NetworkPlayerStatusType { + npst_None = 0x00, + npst_PickSettings = 0x01, + npst_BeRightBack = 0x02, + npst_Ready = 0x04 }; #pragma pack(push, 1) @@ -583,13 +592,14 @@ private: static const int maxPlayernameStringSize= 80; private: - struct Data{ + struct Data { int8 messageType; NetworkString selectedFactionName; //wanted faction name int8 currentFactionIndex; int8 toFactionIndex; int8 toTeam; NetworkString networkPlayerName; + int8 networkPlayerStatus; int8 switchFlags; }; @@ -599,7 +609,8 @@ private: public: SwitchSetupRequest(); SwitchSetupRequest( string selectedFactionName, int8 currentFactionIndex, - int8 toFactionIndex,int8 toTeam,string networkPlayerName, int8 flags); + int8 toFactionIndex,int8 toTeam,string networkPlayerName, + int8 networkPlayerStatus, int8 flags); string getSelectedFactionName() const {return data.selectedFactionName.getString();} int getCurrentFactionIndex() const {return data.currentFactionIndex;} @@ -610,6 +621,8 @@ public: void addSwitchFlag(SwitchSetupRequestFlagType flag) { data.switchFlags |= flag;} void clearSwitchFlag(SwitchSetupRequestFlagType flag) { data.switchFlags &= ~flag;} + int getNetworkPlayerStatus() { return data.networkPlayerStatus; } + virtual bool receive(Socket* socket); virtual void send(Socket* socket) const; }; diff --git a/source/shared_lib/include/platform/posix/socket.h b/source/shared_lib/include/platform/posix/socket.h index 9a278ab5..2adb96e5 100644 --- a/source/shared_lib/include/platform/posix/socket.h +++ b/source/shared_lib/include/platform/posix/socket.h @@ -121,6 +121,9 @@ protected: Mutex dataSynchAccessorRead; Mutex dataSynchAccessorWrite; + Mutex inSocketDestructorSynchAccessor; + bool inSocketDestructor; + public: Socket(PLATFORM_SOCKET sock); Socket(); diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index ae620565..c39c6b55 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -753,6 +753,10 @@ bool Socket::isSocketValid(const PLATFORM_SOCKET *validateSocket) { Socket::Socket(PLATFORM_SOCKET sock) { //this->pingThread = NULL; + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + this->inSocketDestructor = false; + safeMutexSocketDestructorFlag.ReleaseLock(); + this->sock= sock; this->connectedIpAddress = ""; } @@ -761,6 +765,10 @@ Socket::Socket() { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); //this->pingThread = NULL; + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + this->inSocketDestructor = false; + safeMutexSocketDestructorFlag.ReleaseLock(); + this->connectedIpAddress = ""; sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -823,6 +831,10 @@ Socket::~Socket() { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + this->inSocketDestructor = true; + safeMutexSocketDestructorFlag.ReleaseLock(); + disconnectSocket(); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock); @@ -1037,6 +1049,12 @@ int Socket::send(const void *data, int dataSize) { //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); errno = 0; + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + if(this->inSocketDestructor == true) { + return -1; + } + safeMutexSocketDestructorFlag.ReleaseLock(); + MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,string(__FILE__) + "_" + intToStr(__LINE__)); //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -1072,6 +1090,12 @@ int Socket::send(const void *data, int dataSize) { if(isConnected() == true) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + if(this->inSocketDestructor == true) { + return -1; + } + safeMutexSocketDestructorFlag.ReleaseLock(); + MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,string(__FILE__) + "_" + intToStr(__LINE__)); #ifdef __APPLE__ bytesSent = ::send(sock, (const char *)data, dataSize, SO_NOSIGPIPE); @@ -1113,6 +1137,12 @@ int Socket::send(const void *data, int dataSize) { if(isConnected() == true) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + if(this->inSocketDestructor == true) { + return -1; + } + safeMutexSocketDestructorFlag.ReleaseLock(); + MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,string(__FILE__) + "_" + intToStr(__LINE__)); const char *sendBuf = (const char *)data; #ifdef __APPLE__ @@ -1173,6 +1203,12 @@ int Socket::receive(void *data, int dataSize) { ssize_t bytesReceived = 0; if(isSocketValid() == true) { + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + if(this->inSocketDestructor == true) { + return -1; + } + safeMutexSocketDestructorFlag.ReleaseLock(); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + "_" + intToStr(__LINE__)); bytesReceived = recv(sock, reinterpret_cast(data), dataSize, 0); safeMutex.ReleaseLock(); @@ -1195,6 +1231,12 @@ int Socket::receive(void *data, int dataSize) { break; } else if(Socket::isReadable() == true) { + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + if(this->inSocketDestructor == true) { + return -1; + } + safeMutexSocketDestructorFlag.ReleaseLock(); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + "_" + intToStr(__LINE__)); bytesReceived = recv(sock, reinterpret_cast(data), dataSize, 0); safeMutex.ReleaseLock(); @@ -1224,6 +1266,12 @@ int Socket::peek(void *data, int dataSize,bool mustGetData) { if(isSocketValid() == true) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + if(this->inSocketDestructor == true) { + return -1; + } + safeMutexSocketDestructorFlag.ReleaseLock(); + //MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(sock) + "_" + intToStr(dataSize)); static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(&dataSynchAccessorRead,mutexOwnerId); @@ -1265,6 +1313,13 @@ int Socket::peek(void *data, int dataSize,bool mustGetData) { } */ if(Socket::isReadable() == true) { + + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + if(this->inSocketDestructor == true) { + return -1; + } + safeMutexSocketDestructorFlag.ReleaseLock(); + //MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(sock) + "_" + intToStr(dataSize)); MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + string("_") + intToStr(__LINE__)); err = recv(sock, reinterpret_cast(data), dataSize, MSG_PEEK); @@ -1334,6 +1389,12 @@ bool Socket::isReadable() { int i = 0; { + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + if(this->inSocketDestructor == true) { + return false; + } + safeMutexSocketDestructorFlag.ReleaseLock(); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + "_" + intToStr(__LINE__)); i= select((int)sock + 1, &set, NULL, NULL, &tv); } @@ -1357,6 +1418,12 @@ bool Socket::isWritable() { int i = 0; { + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + if(this->inSocketDestructor == true) { + return false; + } + safeMutexSocketDestructorFlag.ReleaseLock(); + MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,string(__FILE__) + "_" + intToStr(__LINE__)); i = select((int)sock + 1, NULL, &set, NULL, &tv); }