diff --git a/source/glest_game/game/chat_manager.cpp b/source/glest_game/game/chat_manager.cpp index 3214e7deb..a288e194b 100644 --- a/source/glest_game/game/chat_manager.cpp +++ b/source/glest_game/game/chat_manager.cpp @@ -158,9 +158,10 @@ void ChatManager::keyDown(SDL_KeyboardEvent key) { } } else if(isKeyPressed(SDLK_TAB,key, false) == true) { - // First find the prefix characters to auto-complete - string autoCompleteName = ""; if(text.empty() == false) { + // First find the prefix characters to auto-complete + string currentAutoCompleteName = ""; + int startPos = -1; for(int i = text.size()-1; i >= 0; --i) { if(text[i] != ' ') { @@ -172,45 +173,144 @@ void ChatManager::keyDown(SDL_KeyboardEvent key) { } if(startPos >= 0) { - autoCompleteName = text.substr(startPos); + currentAutoCompleteName = text.substr(startPos); + } - // Now lookup the prefix for a match in playernames - string autoCompleteResult = ""; - GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); - const GameSettings *settings = gameNetworkInterface->getGameSettings(); - for(unsigned int factionIndex = 0; factionIndex < settings->getFactionCount(); ++factionIndex) { - string playerName = settings->getNetworkPlayerName(factionIndex); - if(playerName.length() > autoCompleteName.length() && - StartsWith(toLower(playerName), toLower(autoCompleteName)) == true) { + //printf("TAB currentAutoCompleteName [%s] lastAutoCompleteSearchText [%s]\n",currentAutoCompleteName.c_str(),lastAutoCompleteSearchText.c_str()); + string autoCompleteName = lastAutoCompleteSearchText; + + // Now lookup the prefix for a match in playernames + string autoCompleteResult = ""; + + int replaceCurrentAutoCompleteName = -1; + vector matchedIndexes; + + GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + const GameSettings *settings = gameNetworkInterface->getGameSettings(); + for(unsigned int factionIndex = 0; factionIndex < settings->getFactionCount(); ++factionIndex) { + string playerName = settings->getNetworkPlayerName(factionIndex); + if(playerName.length() > autoCompleteName.length() && + StartsWith(toLower(playerName), toLower(autoCompleteName)) == true) { + if(toLower(playerName) == toLower(currentAutoCompleteName)) { + replaceCurrentAutoCompleteName = factionIndex; + } + else { autoCompleteResult = playerName.substr(autoCompleteName.length()); + matchedIndexes.push_back(factionIndex); + } + } + } + if(matchedIndexes.size() > 0) { + int newMatchedIndex = -1; + for(unsigned int index = 0; index < matchedIndexes.size(); ++index) { + int possibleMatchIndex = matchedIndexes[index]; + if(replaceCurrentAutoCompleteName < 0 || + (replaceCurrentAutoCompleteName >= 0 && possibleMatchIndex > replaceCurrentAutoCompleteName)) { + newMatchedIndex = possibleMatchIndex; break; } } - - if(autoCompleteResult != "") { - WString addText(autoCompleteResult); - appendText(addText.cw_str(), false); + if(newMatchedIndex < 0) { + for(unsigned int index = 0; index < matchedIndexes.size(); ++index) { + int possibleMatchIndex = matchedIndexes[index]; + if(replaceCurrentAutoCompleteName < 0 || + (replaceCurrentAutoCompleteName >= 0 && possibleMatchIndex < replaceCurrentAutoCompleteName)) { + newMatchedIndex = possibleMatchIndex; + break; + } + } } + + if(newMatchedIndex >= 0) { + autoCompleteResult = settings->getNetworkPlayerName(newMatchedIndex).substr(autoCompleteName.length()); + } + } + + if(autoCompleteResult == "") { + replaceCurrentAutoCompleteName = -1; + matchedIndexes.clear(); + for(unsigned int index = 0; index < autoCompleteTextList.size(); ++index) { + string autoText = autoCompleteTextList[index]; + + //printf("CHECKING #2 autoText.length() = %d [%s] autoCompleteName.length() = %d [%s]\n",autoText.length(),autoText.c_str(),autoCompleteName.length(),currentAutoCompleteName.c_str()); + + if(autoText.length() > autoCompleteName.length() && + StartsWith(toLower(autoText), toLower(autoCompleteName)) == true) { + + if(toLower(autoText) == toLower(currentAutoCompleteName)) { + replaceCurrentAutoCompleteName = index; + //printf("CHECKING #2 REPLACE\n"); + } + else { + autoCompleteResult = autoText.substr(autoCompleteName.length()); + //printf("CHECKING #2 autoCompleteResult [%s] autoCompleteName [%s]\n",autoCompleteResult.c_str(),autoCompleteName.c_str()); + matchedIndexes.push_back(index); + } + } + } + if(matchedIndexes.size() > 0) { + int newMatchedIndex = -1; + for(unsigned int index = 0; index < matchedIndexes.size(); ++index) { + int possibleMatchIndex = matchedIndexes[index]; + if(replaceCurrentAutoCompleteName < 0 || + (replaceCurrentAutoCompleteName >= 0 && possibleMatchIndex > replaceCurrentAutoCompleteName)) { + newMatchedIndex = possibleMatchIndex; + break; + } + } + if(newMatchedIndex < 0) { + for(unsigned int index = 0; index < matchedIndexes.size(); ++index) { + int possibleMatchIndex = matchedIndexes[index]; + if(replaceCurrentAutoCompleteName < 0 || + (replaceCurrentAutoCompleteName >= 0 && possibleMatchIndex < replaceCurrentAutoCompleteName)) { + newMatchedIndex = possibleMatchIndex; + break; + } + } + } + + if(newMatchedIndex >= 0) { + autoCompleteResult = autoCompleteTextList[newMatchedIndex].substr(autoCompleteName.length()); + } + } + } + + if(autoCompleteResult != "") { + if(replaceCurrentAutoCompleteName >= 0) { + deleteText(currentAutoCompleteName.length(), false); + + autoCompleteResult = autoCompleteName + autoCompleteResult; + + //printf("REPLACE: currentAutoCompleteName [%s] autoCompleteResult [%s] text [%s]\n",currentAutoCompleteName.c_str(),autoCompleteResult.c_str(),text.c_str()); + } + else { + //printf("ADD: currentAutoCompleteName [%s] autoCompleteResult [%s] text [%s]\n",currentAutoCompleteName.c_str(),autoCompleteResult.c_str(),text.c_str()); + } + WString addText(autoCompleteResult); + appendText(addText.cw_str(), false, false); } } } else if(isKeyPressed(SDLK_BACKSPACE,key,false) == true) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym,key.keysym.sym); - if(text.empty() == false) { - if(textCharLength.size() > 0) { - //printf("BEFORE DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); - - if(textCharLength[textCharLength.size()-1] > text.length()) { - textCharLength[textCharLength.size()-1] = text.length(); - } - for(unsigned int i = 0; i < textCharLength[textCharLength.size()-1]; ++i) { - text.erase(text.end() -1); - } - //printf("AFTER DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); - textCharLength.pop_back(); - } - } +// if(text.empty() == false) { +// if(textCharLength.size() > 0) { +// //printf("BEFORE DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); +// +// if(textCharLength[textCharLength.size()-1] > text.length()) { +// textCharLength[textCharLength.size()-1] = text.length(); +// } +// for(unsigned int i = 0; i < textCharLength[textCharLength.size()-1]; ++i) { +// text.erase(text.end() -1); +// } +// //printf("AFTER DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); +// textCharLength.pop_back(); +// +// updateAutoCompleteBuffer(); +// } +// } + deleteText(1); } } @@ -230,7 +330,31 @@ void ChatManager::switchOnEdit() { textCharLength.clear(); } -void ChatManager::appendText(const wchar_t *addText, bool validateChars) { +void ChatManager::deleteText(int deleteCount,bool addToAutoCompleteBuffer) { + if(text.empty() == false) { + for(unsigned int i = 0; i < deleteCount; ++i) { + if(textCharLength.size() > 0) { + //printf("BEFORE DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); + + if(textCharLength[textCharLength.size()-1] > text.length()) { + textCharLength[textCharLength.size()-1] = text.length(); + } + for(unsigned int i = 0; i < textCharLength[textCharLength.size()-1]; ++i) { + text.erase(text.end() -1); + } + //printf("AFTER DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); + textCharLength.pop_back(); + + if(addToAutoCompleteBuffer == true) { + updateAutoCompleteBuffer(); + } + } + } + } + +} + +void ChatManager::appendText(const wchar_t *addText, bool validateChars, bool addToAutoCompleteBuffer) { for(unsigned int i = 0; i < wcslen(addText); ++i) { wchar_t key = addText[i]; if(validateChars == false || isAllowedInputTextKey(key)) { @@ -254,6 +378,28 @@ void ChatManager::appendText(const wchar_t *addText, bool validateChars) { //printf("3 char, textCharLength = %d\n",textCharLength.size()); } text += buf; + + if(addToAutoCompleteBuffer == true) { + updateAutoCompleteBuffer(); + } + } + } +} + +void ChatManager::updateAutoCompleteBuffer() { + if(text.empty() == false) { + int startPos = -1; + for(int i = text.size()-1; i >= 0; --i) { + if(text[i] != ' ') { + startPos = i; + } + else { + break; + } + } + + if(startPos >= 0) { + lastAutoCompleteSearchText = text.substr(startPos); } } } diff --git a/source/glest_game/game/chat_manager.h b/source/glest_game/game/chat_manager.h index 246f6bb7d..682b0026d 100644 --- a/source/glest_game/game/chat_manager.h +++ b/source/glest_game/game/chat_manager.h @@ -48,9 +48,13 @@ private: int maxTextLenght; Font2D *font; Font3D *font3D; - - void appendText(const wchar_t *addText, bool validateChars=true); + string lastAutoCompleteSearchText; + vector autoCompleteTextList; + + void appendText(const wchar_t *addText, bool validateChars=true,bool addToAutoCompleteBuffer=true); + void deleteText(int deleteCount,bool addToAutoCompleteBuffer=true); + void updateAutoCompleteBuffer(); public: ChatManager(); @@ -81,6 +85,8 @@ public: bool getDisableTeamMode() const { return disableTeamMode; } void setDisableTeamMode(bool value); + + void setAutoCompleteTextList(vector list) { autoCompleteTextList = list; } }; }}//end namespace diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index e9515b3e4..5b2ee4489 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -48,6 +48,9 @@ const int CANCEL_SWITCH_TEAM = -1; int fadeMusicMilliseconds = 3500; +// Check every x seconds if we should switch disconnected players to AI +const int NETWORK_PLAYER_CONNECTION_CHECK_SECONDS = 5; + Game::Game() : ProgramState(NULL) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -108,6 +111,7 @@ Game::Game() : ProgramState(NULL) { //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",__FILE__,__FUNCTION__,__LINE__,currentAmbientSound); fadeMusicMilliseconds = Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds",intToStr(fadeMusicMilliseconds).c_str()); + lastNetworkPlayerConnectionCheck = time(NULL); } void Game::resetMembers() { @@ -177,6 +181,7 @@ void Game::resetMembers() { //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",__FILE__,__FUNCTION__,__LINE__,currentAmbientSound); fadeMusicMilliseconds = Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds",intToStr(fadeMusicMilliseconds).c_str()); + lastNetworkPlayerConnectionCheck = time(NULL); Object::setStateCallback(&gui); @@ -1366,7 +1371,9 @@ void Game::update() { } void Game::ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRole role) { - if(role == nrServer && isNetworkGame == true) { + if(role == nrServer && isNetworkGame == true && + difftime(time(NULL),lastNetworkPlayerConnectionCheck) >= NETWORK_PLAYER_CONNECTION_CHECK_SECONDS) { + lastNetworkPlayerConnectionCheck = time(NULL); Logger &logger= Logger::getInstance(); ServerInterface *server = NetworkManager::getInstance().getServerInterface(); @@ -1378,8 +1385,10 @@ void Game::ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRo faction->getControlType() == ctNetworkCpu || faction->getControlType() == ctNetworkCpuUltra || faction->getControlType() == ctNetworkCpuMega)) { - ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex()); - if(aiInterfaces[i] == NULL && (slot == NULL || slot->isConnected() == false)) { + //ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex()); + //if(aiInterfaces[i] == NULL && (slot == NULL || slot->isConnected() == false)) { + if(aiInterfaces[i] == NULL && + server->isClientConnected(faction->getStartLocationIndex()) == false) { faction->setFactionDisconnectHandled(true); char szBuf[255]=""; diff --git a/source/glest_game/game/game.h b/source/glest_game/game/game.h index 5bedbb4d2..400fb2715 100644 --- a/source/glest_game/game/game.h +++ b/source/glest_game/game/game.h @@ -147,6 +147,8 @@ private: StrSound *currentAmbientSound; + time_t lastNetworkPlayerConnectionCheck; + public: Game(); Game(Program *program, const GameSettings *gameSettings, bool masterserverMode); diff --git a/source/glest_game/menu/menu_state_masterserver.cpp b/source/glest_game/menu/menu_state_masterserver.cpp index aadb4e516..ab196870b 100644 --- a/source/glest_game/menu/menu_state_masterserver.cpp +++ b/source/glest_game/menu/menu_state_masterserver.cpp @@ -786,7 +786,8 @@ void MenuStateMasterserver::update() { userButtons.push_back(button); } userScrollBar.setElementCount(userButtons.size()); - oldNickList=nickList; + oldNickList = nickList; + chatManager.setAutoCompleteTextList(oldNickList); } if(userScrollBar.getElementCount()!=0 ) { for(int i = userScrollBar.getVisibleStart(); i <= userScrollBar.getVisibleEnd(); ++i) { diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index 9e1e30a60..9f75a9d0a 100644 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -175,7 +175,7 @@ std::string ClientInterface::getServerIpAddress() { } void ClientInterface::updateLobby() { - NetworkMessageType networkMessageType = getNextMessageType(true); + NetworkMessageType networkMessageType = getNextMessageType(); switch(networkMessageType) { case nmtInvalid: @@ -544,7 +544,7 @@ void ClientInterface::updateKeyframe(int frameCount) { // END: Test simulating lag for the client //check we have an expected message - //NetworkMessageType networkMessageType= getNextMessageType(true); + //NetworkMessageType networkMessageType= getNextMessageType(); switch(networkMessageType) { @@ -725,7 +725,7 @@ void ClientInterface::waitUntilReady(Checksum* checksum) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); return; } - NetworkMessageType networkMessageType = getNextMessageType(true); + NetworkMessageType networkMessageType = getNextMessageType(); // consume old messages from the lobby bool discarded = shouldDiscardNetworkMessage(networkMessageType); @@ -1036,11 +1036,11 @@ NetworkMessageType ClientInterface::waitForMessage() chrono.start(); NetworkMessageType msg = nmtInvalid; - uint64 waitLoopCount = 0; + //uint64 waitLoopCount = 0; while(msg == nmtInvalid) { - msg = getNextMessageType(true); + msg = getNextMessageType(); if(msg == nmtInvalid) { - if(chrono.getMillis() % 150 == 0 && isConnected() == false) { + if(chrono.getMillis() % 250 == 0 && isConnected() == false) { if(quit == false) { //throw runtime_error("Disconnected"); //sendTextMessage("Server has Disconnected.",-1); @@ -1082,10 +1082,11 @@ NetworkMessageType ClientInterface::waitForMessage() //sleep(waitSleepTime); } - waitLoopCount++; + //waitLoopCount++; } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] waiting took %lld msecs, waitLoopCount = %ull, msg = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),waitLoopCount,msg); + //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] waiting took %lld msecs, waitLoopCount = %ull, msg = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),waitLoopCount,msg); + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] waiting took %lld msecs, msg = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),msg); return msg; } diff --git a/source/glest_game/network/client_interface.h b/source/glest_game/network/client_interface.h index c39ee9fd3..c8536bea6 100644 --- a/source/glest_game/network/client_interface.h +++ b/source/glest_game/network/client_interface.h @@ -61,8 +61,8 @@ public: ClientInterface(); virtual ~ClientInterface(); - virtual Socket* getSocket() {return clientSocket;} - virtual const Socket* getSocket() const {return clientSocket;} + virtual Socket* getSocket(bool mutexLock=true) {return clientSocket;} + //virtual const Socket* getSocket() const {return clientSocket;} virtual void close(); //message processing diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index ac898f207..8eef0b23a 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -292,7 +292,7 @@ void ConnectionSlot::updateSlot(ConnectionSlotEvent *event) { if(event != NULL) { bool &socketTriggered = event->socketTriggered; - bool checkForNewClients = true; + bool checkForNewClients = (serverInterface->getGameHasBeenInitiated() == false); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); @@ -301,7 +301,8 @@ void ConnectionSlot::updateSlot(ConnectionSlotEvent *event) { if((serverInterface->getGameHasBeenInitiated() == false || //(this->getSocket() != NULL && socketTriggered == true))) { socketTriggered == true)) { - if(socketTriggered == true || this->isConnected() == false) { + if(socketTriggered == true || + (serverInterface->getGameHasBeenInitiated() == false && this->isConnected() == false)) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); @@ -469,7 +470,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { for(;this->hasDataToRead() == true && gotTextMsg == true;) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] polling for networkMessageType...\n",__FILE__,__FUNCTION__,__LINE__); - NetworkMessageType networkMessageType= getNextMessageType(true); + NetworkMessageType networkMessageType= getNextMessageType(); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] networkMessageType = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageType); @@ -1147,8 +1148,11 @@ pair ConnectionSlot::getSocketInfo() { } -Socket* ConnectionSlot::getSocket() { - MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); +Socket* ConnectionSlot::getSocket(bool mutexLock) { + MutexSafeWrapper safeMutexSlot(NULL,CODE_AT_LINE); + if(mutexLock == true) { + safeMutexSlot.setMutex(&mutexSocket,CODE_AT_LINE); + } return socket; } diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index 3a133240a..dfebcf820 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -146,7 +146,7 @@ public: void setName(string value) {name = value;} bool isReady() const {return ready;} - virtual Socket* getSocket(); + virtual Socket* getSocket(bool mutexLock=true); pair getSocketInfo(); virtual void close(); diff --git a/source/glest_game/network/network_interface.cpp b/source/glest_game/network/network_interface.cpp index b63c517f6..4ac715bf9 100644 --- a/source/glest_game/network/network_interface.cpp +++ b/source/glest_game/network/network_interface.cpp @@ -39,30 +39,29 @@ bool NetworkInterface::allowDownloadDataSynch = false; DisplayMessageFunction NetworkInterface::pCB_DisplayMessage = NULL; void NetworkInterface::sendMessage(const NetworkMessage* networkMessage){ - Socket* socket= getSocket(); + Socket* socket= getSocket(false); networkMessage->send(socket); } -NetworkMessageType NetworkInterface::getNextMessageType(bool checkHasDataFirst) +NetworkMessageType NetworkInterface::getNextMessageType() { - Socket* socket= getSocket(); + Socket* socket= getSocket(false); int8 messageType= nmtInvalid; - if(checkHasDataFirst == false || - (checkHasDataFirst == true && - socket != NULL && - socket->hasDataToRead() == true)) - { + if(socket != NULL && + socket->hasDataToRead() == true) { //peek message type int dataSize = socket->getDataToRead(); - if(dataSize >= sizeof(messageType)){ + if(dataSize >= sizeof(messageType)) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,dataSize); + int iPeek = socket->peek(&messageType, sizeof(messageType)); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,iPeek,messageType,sizeof(messageType)); } else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d, checkHasDataFirst = %d\n",__FILE__,__FUNCTION__,__LINE__,messageType,sizeof(messageType),dataSize,checkHasDataFirst); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,messageType,sizeof(messageType),dataSize); } //sanity check new message type @@ -83,7 +82,7 @@ bool NetworkInterface::receiveMessage(NetworkMessage* networkMessage){ if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s]\n",__FILE__,__FUNCTION__); - Socket* socket= getSocket(); + Socket* socket= getSocket(false); return networkMessage->receive(socket); } @@ -119,8 +118,9 @@ void NetworkInterface::clearChatInfo() { std::string NetworkInterface::getIpAddress() { std::string result = ""; - if(getSocket() != NULL) { - result = getSocket()->getIpAddress(); + Socket *socket = getSocket(); + if(socket != NULL) { + result = socket->getIpAddress(); } return result; } diff --git a/source/glest_game/network/network_interface.h b/source/glest_game/network/network_interface.h index d812aa147..f816dddfc 100644 --- a/source/glest_game/network/network_interface.h +++ b/source/glest_game/network/network_interface.h @@ -108,7 +108,7 @@ public: public: virtual ~NetworkInterface(){} - virtual Socket* getSocket()= 0; + virtual Socket* getSocket(bool mutexLock=true)= 0; virtual void close()= 0; virtual string getHumanPlayerName(int index=-1) = 0; virtual int getHumanPlayerIndex() const = 0; @@ -120,7 +120,7 @@ public: string getHostName() const {return Socket::getHostName();} virtual void sendMessage(const NetworkMessage* networkMessage); - NetworkMessageType getNextMessageType(bool checkHasDataFirst = false); + NetworkMessageType getNextMessageType(); bool receiveMessage(NetworkMessage* networkMessage); virtual bool isConnected(); diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 4d9aece41..b8ec74f57 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -346,14 +346,24 @@ void ServerInterface::removeSlot(int playerIndex, int lockedSlotIndex) { } ConnectionSlot *ServerInterface::getSlot(int playerIndex) { - return slots[playerIndex]; + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[playerIndex],CODE_AT_LINE_X(i)); + ConnectionSlot *result = slots[playerIndex]; + return result; +} + +bool ServerInterface::isClientConnected(int index) { + bool result = false; + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[index],CODE_AT_LINE_X(i)); + if(slots[index] != NULL && slots[index]->isConnected() == true) { + result = true; + } + return result; } bool ServerInterface::hasClientConnection() { bool result = false; for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); - if(slots[i] != NULL && slots[i]->isConnected() == true) { + if(isClientConnected(i) == true) { result = true; break; } @@ -1225,7 +1235,7 @@ void ServerInterface::waitUntilReady(Checksum *checksum) { ConnectionSlot* connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected() == true) { if(connectionSlot->isReady() == false) { - NetworkMessageType networkMessageType= connectionSlot->getNextMessageType(true); + NetworkMessageType networkMessageType= connectionSlot->getNextMessageType(); // consume old messages from the lobby bool discarded = shouldDiscardNetworkMessage(networkMessageType,connectionSlot); diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index 4f3b2d9c2..b79a2924a 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -91,11 +91,11 @@ public: ServerInterface(bool publishEnabled); virtual ~ServerInterface(); - virtual Socket* getSocket() {return &serverSocket;} + virtual Socket* getSocket(bool mutexLock=true) {return &serverSocket;} - const virtual Socket *getSocket() const { - return &serverSocket; - } + //const virtual Socket *getSocket() const { + // return &serverSocket; + //} virtual void close(); virtual void update(); @@ -140,6 +140,8 @@ public: virtual void slotUpdateTask(ConnectionSlotEvent *event); bool hasClientConnection(); + bool isClientConnected(int index); + int getCurrentFrameCount() const { return currentFrameCount; diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index 72707f9c4..68c5cbf1c 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -1039,7 +1039,7 @@ int Socket::getDataToRead(bool wantImmediateReply) { //if(retval) if(isSocketValid() == true) { - int loopCount = 1; + //int loopCount = 1; for(time_t elapsed = time(NULL); difftime(time(NULL),elapsed) < 1;) { /* ioctl isn't posix, but the following seems to work on all modern * unixes */ @@ -1065,10 +1065,12 @@ int Socket::getDataToRead(bool wantImmediateReply) { break; } else if(hasDataToRead() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, (hasDataToRead() == true) err = %d, sock = %d, size = %lu, loopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size,loopCount); + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, (hasDataToRead() == true) err = %d, sock = %d, size = %lu, loopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size,loopCount); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, (hasDataToRead() == true) err = %d, sock = %d, size = %lu\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size); } else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, err = %d, sock = %d, size = %lu, loopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size,loopCount); + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, err = %d, sock = %d, size = %lu, loopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size,loopCount); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, err = %d, sock = %d, size = %lu\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size); break; } @@ -1076,7 +1078,7 @@ int Socket::getDataToRead(bool wantImmediateReply) { break; } - loopCount++; + //loopCount++; } } @@ -1475,8 +1477,8 @@ bool Socket::isWritable() { struct timeval tv; tv.tv_sec= 0; - tv.tv_usec= 1; - //tv.tv_usec= 0; + //tv.tv_usec= 1; + tv.tv_usec= 0; fd_set set; FD_ZERO(&set);