diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index bea030088..ca85e9976 100755 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -405,7 +405,7 @@ void ClientInterface::updateKeyframe(int frameCount) { bool done= false; - while(!done) + while(done == false) { //wait for the next message waitForMessage(); @@ -489,13 +489,17 @@ void ClientInterface::updateKeyframe(int frameCount) DisplayErrorMessage(string(__FILE__) + "::" + string(__FUNCTION__) + " Unexpected message in client interface: " + intToStr(networkMessageType)); quit= true; close(); + done= true; } } + + if(isConnected() == false && quit == true) { + done = true; + } } } -void ClientInterface::waitUntilReady(Checksum* checksum) -{ +void ClientInterface::waitUntilReady(Checksum* checksum) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); Logger &logger= Logger::getInstance(); @@ -514,15 +518,15 @@ void ClientInterface::waitUntilReady(Checksum* checksum) int64 lastMillisCheck = 0; //wait until we get a ready message from the server - while(true) - { + while(true) { + if(isConnected() == false) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); string sErr = "Error, Server has disconnected!"; - sendTextMessage(sErr,-1); + //sendTextMessage(sErr,-1); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); DisplayErrorMessage(sErr); @@ -535,18 +539,14 @@ void ClientInterface::waitUntilReady(Checksum* checksum) return; } NetworkMessageType networkMessageType = getNextMessageType(true); - if(networkMessageType == nmtReady) - { - if(receiveMessage(&networkMessageReady)) - { + if(networkMessageType == nmtReady) { + if(receiveMessage(&networkMessageReady)) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); break; } } - else if(networkMessageType == nmtInvalid) - { - if(chrono.getMillis() > readyWaitTimeout) - { + else if(networkMessageType == nmtInvalid) { + if(chrono.getMillis() > readyWaitTimeout) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); //throw runtime_error("Timeout waiting for server"); string sErr = "Timeout waiting for server"; @@ -564,10 +564,8 @@ void ClientInterface::waitUntilReady(Checksum* checksum) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); return; } - else - { - if(chrono.getMillis() / 1000 > lastMillisCheck) - { + else { + if(chrono.getMillis() / 1000 > lastMillisCheck) { lastMillisCheck = (chrono.getMillis() / 1000); char szBuf[1024]=""; @@ -576,8 +574,7 @@ void ClientInterface::waitUntilReady(Checksum* checksum) } } } - else - { + else { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); //throw runtime_error(string(__FILE__) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType) ); sendTextMessage("Unexpected network message: " + intToStr(networkMessageType),-1); @@ -602,8 +599,7 @@ void ClientInterface::waitUntilReady(Checksum* checksum) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); //check checksum - if(networkMessageReady.getChecksum() != checksum->getSum()) - { + if(networkMessageReady.getChecksum() != checksum->getSum()) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); string sErr = "Checksum error, you don't have the same data as the server"; @@ -633,8 +629,7 @@ void ClientInterface::waitUntilReady(Checksum* checksum) return; } - - //delay the start a bit, so clients have nore room to get messages + //delay the start a bit, so clients have more room to get messages sleep(GameConstants::networkExtraLatency); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__); @@ -657,11 +652,11 @@ void ClientInterface::waitForMessage() int waitLoopCount = 0; while(getNextMessageType(true) == nmtInvalid) { - if(!isConnected()) + if(isConnected() == false) { //throw runtime_error("Disconnected"); - sendTextMessage("Disconnected",-1); - DisplayErrorMessage("Disconnected"); + sendTextMessage("Server has Disconnected.",-1); + DisplayErrorMessage("Server has Disconnected."); quit= true; close(); return; diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index 0ce9981de..f1795931f 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -25,7 +25,7 @@ namespace Glest{ namespace Game{ class GameSettings; -enum NetworkMessageType{ +enum NetworkMessageType { nmtInvalid, nmtIntro, nmtPing, @@ -51,7 +51,7 @@ const int32 commandListHeaderSize = 6; // class NetworkMessage // ===================================================== -class NetworkMessage{ +class NetworkMessage { public: virtual ~NetworkMessage(){} virtual bool receive(Socket* socket)= 0; diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 0b8dcde5a..e4f6c656c 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -280,6 +280,79 @@ void ServerInterface::updateKeyframe(int frameCount){ SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] broadcastMessage took %d msecs, networkMessageCommandList.getCommandCount() = %d, frameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkMessageCommandList.getCommandCount(),frameCount); } +bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, + ConnectionSlot* connectionSlot) { + bool discard = false; + if(connectionSlot != NULL) { + switch(networkMessageType) { + case nmtIntro: + { + discard = true; + NetworkMessageIntro msg = NetworkMessageIntro(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtLaunch: + { + discard = true; + NetworkMessageLaunch msg = NetworkMessageLaunch(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtText: + { + discard = true; + NetworkMessageText msg = NetworkMessageText(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtSynchNetworkGameData: + { + discard = true; + NetworkMessageSynchNetworkGameData msg = NetworkMessageSynchNetworkGameData(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtSynchNetworkGameDataStatus: + { + discard = true; + NetworkMessageSynchNetworkGameDataStatus msg = NetworkMessageSynchNetworkGameDataStatus(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtSynchNetworkGameDataFileCRCCheck: + { + discard = true; + NetworkMessageSynchNetworkGameDataFileCRCCheck msg = NetworkMessageSynchNetworkGameDataFileCRCCheck(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtSynchNetworkGameDataFileGet: + { + discard = true; + NetworkMessageSynchNetworkGameDataFileGet msg = NetworkMessageSynchNetworkGameDataFileGet(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtSwitchSetupRequest: + { + discard = true; + SwitchSetupRequest msg = SwitchSetupRequest(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtPlayerIndexMessage: + { + discard = true; + PlayerIndexMessage msg = PlayerIndexMessage(0); + connectionSlot->receiveMessage(&msg); + } + break; + } + } + return discard; +} + void ServerInterface::waitUntilReady(Checksum* checksum){ SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] START\n",__FUNCTION__); @@ -293,44 +366,33 @@ void ServerInterface::waitUntilReady(Checksum* checksum){ chrono.start(); //wait until we get a ready message from all clients - while(allReady == false) - { + while(allReady == false) { vector waitingForHosts; allReady= true; - for(int i= 0; iisConnected() == true) - { - if(connectionSlot->isReady() == false) - { + if(connectionSlot != NULL && connectionSlot->isConnected() == true) { + if(connectionSlot->isReady() == false) { NetworkMessageType networkMessageType= connectionSlot->getNextMessageType(true); - NetworkMessageReady networkMessageReady; - // consume old messages from the setup - while(networkMessageType == nmtSwitchSetupRequest) - { - SwitchSetupRequest switchSetupRequest; - connectionSlot->receiveMessage(&switchSetupRequest); - networkMessageType= connectionSlot->getNextMessageType(true); - } - if(networkMessageType == nmtReady && - connectionSlot->receiveMessage(&networkMessageReady)) - { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] networkMessageType==nmtReady\n",__FUNCTION__); + // consume old messages from the lobby + bool discarded = shouldDiscardNetworkMessage(networkMessageType,connectionSlot); + if(discarded == false) { + NetworkMessageReady networkMessageReady; + if(networkMessageType == nmtReady && + connectionSlot->receiveMessage(&networkMessageReady)) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] networkMessageType==nmtReady\n",__FUNCTION__); - connectionSlot->setReady(); + connectionSlot->setReady(); + } + else if(networkMessageType != nmtInvalid) { + //throw runtime_error("Unexpected network message: " + intToStr(networkMessageType)); + string sErr = "Unexpected network message: " + intToStr(networkMessageType); + sendTextMessage(sErr,-1); + DisplayErrorMessage(sErr); + return; + } } - else if(networkMessageType != nmtInvalid) - { - //throw runtime_error("Unexpected network message: " + intToStr(networkMessageType)); - string sErr = "Unexpected network message: " + intToStr(networkMessageType); - sendTextMessage(sErr,-1); - DisplayErrorMessage(sErr); - return; - } - //waitingForHosts.push_back(connectionSlot->getHostName()); waitingForHosts.push_back(connectionSlot->getName()); @@ -340,25 +402,19 @@ void ServerInterface::waitUntilReady(Checksum* checksum){ } //check for timeout - if(allReady == false) - { - if(chrono.getMillis() > readyWaitTimeout) - { + if(allReady == false) { + if(chrono.getMillis() > readyWaitTimeout) { //throw runtime_error("Timeout waiting for clients"); string sErr = "Timeout waiting for clients."; sendTextMessage(sErr,-1); DisplayErrorMessage(sErr); return; } - else - { - if(chrono.getMillis() % 1000 == 0) - { + else { + if(chrono.getMillis() % 1000 == 0) { string waitForHosts = ""; - for(int i = 0; i < waitingForHosts.size(); i++) - { - if(waitForHosts != "") - { + for(int i = 0; i < waitingForHosts.size(); i++) { + if(waitForHosts != "") { waitForHosts += ", "; } waitForHosts += waitingForHosts[i]; @@ -372,20 +428,16 @@ void ServerInterface::waitUntilReady(Checksum* checksum){ } } - // FOR TESTING ONLY - delay to see the client count up while waiting //sleep(5000); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] PART B (telling client we are ready!\n",__FUNCTION__); //send ready message after, so clients start delayed - for(int i= 0; i < GameConstants::maxPlayers; ++i) - { - NetworkMessageReady networkMessageReady(checksum->getSum()); - + for(int i= 0; i < GameConstants::maxPlayers; ++i) { ConnectionSlot* connectionSlot= slots[i]; - if(connectionSlot!=NULL) - { + if(connectionSlot != NULL && connectionSlot->isConnected() == true) { + NetworkMessageReady networkMessageReady(checksum->getSum()); connectionSlot->sendMessage(&networkMessageReady); } } diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index 468705bb1..efbd7590a 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -82,6 +82,7 @@ private: void broadcastMessage(const NetworkMessage* networkMessage, int excludeSlot= -1); void updateListen(); void broadcastMessageToConnectedClients(const NetworkMessage* networkMessage, int excludeSlot = -1); + bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType,ConnectionSlot* connectionSlot); }; }}//end namespace diff --git a/source/shared_lib/include/util/util.h b/source/shared_lib/include/util/util.h index 656ba44f3..41cb4f5e6 100644 --- a/source/shared_lib/include/util/util.h +++ b/source/shared_lib/include/util/util.h @@ -143,6 +143,28 @@ void deleteMapValues(T beginIt, T endIt){ } } +template +class create_map +{ +private: + std::map m_map; +public: + create_map(const T& key, const U& val) + { + m_map[key] = val; + } + + create_map& operator()(const T& key, const U& val) + { + m_map[key] = val; + return *this; + } + + operator std::map() + { + return m_map; + } +}; }}//end namespace #endif