diff --git a/source/glest_game/facilities/logger.cpp b/source/glest_game/facilities/logger.cpp index aad9dcc37..3cd50e4ad 100644 --- a/source/glest_game/facilities/logger.cpp +++ b/source/glest_game/facilities/logger.cpp @@ -49,6 +49,9 @@ Logger::Logger() { } loadingTexture=NULL; showProgressBar = false; + + cancelSelected = false; + buttonCancel.setEnabled(false); } Logger::~Logger() { @@ -59,24 +62,26 @@ Logger & Logger::getInstance() { return logger; } -void Logger::add(const string &str, bool renderScreen) { - FILE *f=fopen(fileName.c_str(), "at+"); - if(f!=NULL){ +void Logger::add(const string str, bool renderScreen, const string statusText) { + FILE *f = fopen(fileName.c_str(), "at+"); + if(f != NULL){ fprintf(f, "%s\n", str.c_str()); fclose(f); } - current= str; - if(renderScreen){ + this->current= str; + this->statusText = statusText; + + if(renderScreen == true) { renderLoadingScreen(); } } void Logger::clear() { - string s="Log file\n"; + string s = "Log file\n"; FILE *f= fopen(fileName.c_str(), "wt+"); - if(f==NULL){ - throw runtime_error("Error opening log file"+ fileName); + if(f == NULL){ + throw runtime_error("Error opening log file" + fileName); } fprintf(f, "%s", s.c_str()); @@ -86,21 +91,26 @@ void Logger::clear() { } void Logger::loadLoadingScreen(string filepath) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(filepath=="") - { - loadingTexture=NULL; + if(filepath == "") { + loadingTexture = NULL; } - else - { + else { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] filepath = [%s]\n",__FILE__,__FUNCTION__,__LINE__,filepath.c_str()); loadingTexture = Renderer::findFactionLogoTexture(filepath); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } } +void Logger::handleMouseClick(int x, int y) { + if(buttonCancel.getEnabled() == true) { + if(buttonCancel.mouseClick(x, y)) { + cancelSelected = true; + } + } +} + // ==================== PRIVATE ==================== void Logger::renderLoadingScreen() { @@ -114,7 +124,7 @@ void Logger::renderLoadingScreen() { if(loadingTexture == NULL) { renderer.renderBackground(CoreData::getInstance().getBackgroundTexture()); } - else{ + else { renderer.renderBackground(loadingTexture); } renderer.renderText( @@ -123,19 +133,41 @@ void Logger::renderLoadingScreen() { renderer.renderText( current, coreData.getMenuFontNormal(), 1.0f, - metrics.getVirtualW()/4, - 62*metrics.getVirtualH()/100, false); + metrics.getVirtualW() / 4, + 62 * metrics.getVirtualH() / 100, false); if(showProgressBar == true) { renderer.renderProgressBar( progress, - metrics.getVirtualW()/4, - 59*metrics.getVirtualH()/100, + metrics.getVirtualW() / 4, + 59 * metrics.getVirtualH() / 100, coreData.getDisplayFontSmall(), 350,""); // no string here, because it has to be language specific and does not give much information } + if(this->statusText != "") { + renderer.renderText( + this->statusText, coreData.getMenuFontNormal(), 1.0f, + metrics.getVirtualW() / 4, + 56 * metrics.getVirtualH() / 100, false); + } + + if(buttonCancel.getEnabled() == true) { + renderer.renderButton(&buttonCancel); + } + renderer.swapBuffers(); } +void Logger::setCancelLoadingEnabled(bool value) { + Lang &lang= Lang::getInstance(); + const Metrics &metrics= Metrics::getInstance(); + string containerName = "logger"; + //buttonCancel.registerGraphicComponent(containerName,"buttonCancel"); + buttonCancel.init((metrics.getVirtualW() / 2) - (125 / 2), 50 * metrics.getVirtualH() / 100, 125); + buttonCancel.setText(lang.get("Cancel")); + buttonCancel.setEnabled(value); + //GraphicComponent::applyAllCustomProperties(containerName); +} + }}//end namespace diff --git a/source/glest_game/facilities/logger.h b/source/glest_game/facilities/logger.h index 15b743d6d..ca685890c 100644 --- a/source/glest_game/facilities/logger.h +++ b/source/glest_game/facilities/logger.h @@ -16,6 +16,7 @@ #include #include "texture.h" +#include "components.h" #include "leak_dumper.h" using std::string; @@ -30,7 +31,7 @@ namespace Glest{ namespace Game{ /// Interface to write log files // ===================================================== -class Logger{ +class Logger { private: static const int logLineCount; @@ -46,6 +47,10 @@ private: int progress; bool showProgressBar; + string statusText; + bool cancelSelected; + GraphicButton buttonCancel; + private: Logger(); ~Logger(); @@ -61,10 +66,15 @@ public: void showProgress() { showProgressBar = true;} void hideProgress() { showProgressBar = false;} - void add(const string &str, bool renderScreen= false); + void add(const string str, bool renderScreen= false, const string statusText=""); void loadLoadingScreen(string filepath); void renderLoadingScreen(); + void setCancelLoadingEnabled(bool value); + bool getCancelLoading() const { return cancelSelected; } + void setCancelLoading(bool value) { cancelSelected = value; } + void handleMouseClick(int x, int y); + void clear(); }; diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 6dc54d7bf..e7ef249ce 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -1046,6 +1046,7 @@ void Game::tick() { void Game::mouseDownLeft(int x, int y) { try { if(gameStarted == false) { + Logger::getInstance().handleMouseClick(x, y); return; } @@ -1143,6 +1144,7 @@ void Game::mouseDownLeft(int x, int y) { void Game::mouseDownRight(int x, int y) { try { if(gameStarted == false) { + Logger::getInstance().handleMouseClick(x, y); return; } diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index a7bc40145..754416787 100755 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -617,7 +617,10 @@ void ClientInterface::updateKeyframe(int frameCount) { 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()); } break; - case nmtInvalid: + case nmtLoadingStatusMessage: + break; + + case nmtInvalid: break; default: @@ -650,13 +653,18 @@ void ClientInterface::waitUntilReady(Checksum* checksum) { //send ready message NetworkMessageReady networkMessageReady; - sendMessage(&networkMessageReady); + //sendMessage(&networkMessageReady); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + NetworkMessageLoadingStatus networkMessageLoadingStatus(nmls_NONE); + + Lang &lang= Lang::getInstance(); int64 lastMillisCheck = 0; //wait until we get a ready message from the server while(true) { + // FOR TESTING ONLY - delay to see the client count up while waiting + //sleep(2000); if(isConnected() == false) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); @@ -683,6 +691,28 @@ void ClientInterface::waitUntilReady(Checksum* checksum) { break; } } + else if(networkMessageType == nmtLoadingStatusMessage) { + if(receiveMessage(&networkMessageLoadingStatus)) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + } + } + else if(networkMessageType == nmtQuit) { + NetworkMessageQuit networkMessageQuit; + if(receiveMessage(&networkMessageQuit)) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + + DisplayErrorMessage(lang.get("GameCancelledByUser")); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + + quit= true; + close(); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + return; + + } + } else if(networkMessageType == nmtInvalid) { if(chrono.getMillis() > readyWaitTimeout) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); @@ -706,8 +736,87 @@ void ClientInterface::waitUntilReady(Checksum* checksum) { lastMillisCheck = (chrono.getMillis() / 1000); char szBuf[1024]=""; - sprintf(szBuf,"Waiting for network: %lld seconds elapsed (maximum wait time: %d seconds)",(long long int)lastMillisCheck,int(readyWaitTimeout / 1000)); - logger.add(szBuf, true); + string updateTextFormat = lang.get("NetworkGameClientLoadStatus"); + if(updateTextFormat == "" || updateTextFormat[0] == '?') { + updateTextFormat = "Waiting for network: %lld seconds elapsed (maximum wait time: %d seconds)"; + } + + string waitForHosts = ""; + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER1_CONNECTED) == nmls_PLAYER1_CONNECTED) { + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER1_READY) != nmls_PLAYER1_READY) { + if(waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerName(0); + } + } + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER2_CONNECTED) == nmls_PLAYER2_CONNECTED) { + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER2_READY) != nmls_PLAYER2_READY) { + if(waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerName(1); + } + } + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER3_CONNECTED) == nmls_PLAYER3_CONNECTED) { + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER3_READY) != nmls_PLAYER3_READY) { + if(waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerName(2); + } + } + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER4_CONNECTED) == nmls_PLAYER4_CONNECTED) { + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER4_READY) != nmls_PLAYER4_READY) { + if(waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerName(3); + } + } + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER5_CONNECTED) == nmls_PLAYER5_CONNECTED) { + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER5_READY) != nmls_PLAYER5_READY) { + if(waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerName(4); + } + } + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER6_CONNECTED) == nmls_PLAYER6_CONNECTED) { + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER6_READY) != nmls_PLAYER6_READY) { + if(waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerName(5); + } + } + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER7_CONNECTED) == nmls_PLAYER7_CONNECTED) { + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER7_READY) != nmls_PLAYER7_READY) { + if(waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerName(6); + } + } + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER8_CONNECTED) == nmls_PLAYER8_CONNECTED) { + if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER8_READY) != nmls_PLAYER8_READY) { + if(waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerName(7); + } + } + + sprintf(szBuf,updateTextFormat.c_str(),(long long int)lastMillisCheck,int(readyWaitTimeout / 1000)); + + char szBuf1[1024]=""; + string statusTextFormat = lang.get("NetworkGameStatusWaiting"); + if(statusTextFormat == "" || statusTextFormat[0] == '?') { + statusTextFormat = "Waiting for players: %s"; + } + sprintf(szBuf1,statusTextFormat.c_str(),waitForHosts.c_str()); + + logger.add(szBuf, true, szBuf1); } } } diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index 8038ffa72..4bfbe66d7 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -731,6 +731,9 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { // its simply ignored here. Probably we are starting a game break; } + case nmtLoadingStatusMessage: + break; + default: { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] networkMessageType = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageType); diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index 00a77fe4a..752e5bfca 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -1001,8 +1001,6 @@ void SwitchSetupRequest::send(Socket* socket) const { // ===================================================== // class PlayerIndexMessage // ===================================================== - - PlayerIndexMessage::PlayerIndexMessage(int16 playerIndex) { data.messageType= nmtPlayerIndexMessage; @@ -1020,5 +1018,24 @@ void PlayerIndexMessage::send(Socket* socket) const NetworkMessage::send(socket, &data, sizeof(data)); } +// ===================================================== +// class NetworkMessageLoadingStatus +// ===================================================== +NetworkMessageLoadingStatus::NetworkMessageLoadingStatus(uint32 status) +{ + data.messageType= nmtLoadingStatusMessage; + data.status=status; +} + +bool NetworkMessageLoadingStatus::receive(Socket* socket) +{ + return NetworkMessage::receive(socket, &data, sizeof(data)); +} + +void NetworkMessageLoadingStatus::send(Socket* socket) const +{ + assert(data.messageType==nmtLoadingStatusMessage); + NetworkMessage::send(socket, &data, sizeof(data)); +} }}//end namespace diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index 94688554a..c1c45b229 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -42,6 +42,7 @@ enum NetworkMessageType { nmtBroadCastSetup, nmtSwitchSetupRequest, nmtPlayerIndexMessage, + nmtLoadingStatusMessage, nmtCount }; @@ -661,6 +662,57 @@ public: }; #pragma pack(pop) +// ===================================================== +// class NetworkMessageLoadingStatus +// +// Message sent during game loading +// ===================================================== + +enum NetworkMessageLoadingStatusType { + nmls_NONE = 0x00, + + nmls_PLAYER1_CONNECTED = 0x01, + nmls_PLAYER2_CONNECTED = 0x02, + nmls_PLAYER3_CONNECTED = 0x04, + nmls_PLAYER4_CONNECTED = 0x08, + nmls_PLAYER5_CONNECTED = 0x10, + nmls_PLAYER6_CONNECTED = 0x20, + nmls_PLAYER7_CONNECTED = 0x40, + nmls_PLAYER8_CONNECTED = 0x80, + + nmls_PLAYER1_READY = 0x100, + nmls_PLAYER2_READY = 0x200, + nmls_PLAYER3_READY = 0x400, + nmls_PLAYER4_READY = 0x1000, + nmls_PLAYER5_READY = 0x2000, + nmls_PLAYER6_READY = 0x4000, + nmls_PLAYER7_READY = 0x8000, + nmls_PLAYER8_READY = 0x10000 +}; + +#pragma pack(push, 1) +class NetworkMessageLoadingStatus : public NetworkMessage { +private: + struct Data{ + int8 messageType; + uint32 status; + }; + +private: + Data data; + +public: + NetworkMessageLoadingStatus(); + NetworkMessageLoadingStatus(uint32 status); + + uint32 getStatus() const {return data.status;} + + virtual bool receive(Socket* socket); + virtual void send(Socket* socket) const; +}; +#pragma pack(pop) + + }}//end namespace #endif diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index c15a4a94c..8a31ccb24 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -1009,7 +1009,10 @@ void ServerInterface::waitUntilReady(Checksum *checksum) { bool allReady = false; - while(exitServer == false && allReady == false) { + logger.setCancelLoadingEnabled(true); + + Lang &lang= Lang::getInstance(); + while(exitServer == false && allReady == false && logger.getCancelLoading() == false) { vector waitingForHosts; allReady= true; for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { @@ -1033,6 +1036,7 @@ void ServerInterface::waitUntilReady(Checksum *checksum) { string sErr = "Unexpected network message: " + intToStr(networkMessageType); sendTextMessage(sErr,-1, true,i); DisplayErrorMessage(sErr); + logger.setCancelLoading(false); return; } } @@ -1049,6 +1053,7 @@ void ServerInterface::waitUntilReady(Checksum *checksum) { string sErr = "Timeout waiting for clients."; sendTextMessage(sErr,-1, true); DisplayErrorMessage(sErr); + logger.setCancelLoading(false); return; } else { @@ -1062,14 +1067,107 @@ void ServerInterface::waitUntilReady(Checksum *checksum) { } char szBuf[1024]=""; - sprintf(szBuf,"Waiting for network: %d of %d max seconds (waiting for: %s)",int(chrono.getMillis() / 1000),int(readyWaitTimeout / 1000),waitForHosts.c_str()); - logger.add(szBuf, true); + string updateTextFormat = lang.get("NetworkGameServerLoadStatus"); + if(updateTextFormat == "" || updateTextFormat[0] == '?') { + updateTextFormat = "Waiting for network: %lld seconds elapsed (maximum wait time: %d seconds)"; + } + sprintf(szBuf,updateTextFormat.c_str(),(long long int)(chrono.getMillis() / 1000),int(readyWaitTimeout / 1000)); + + char szBuf1[1024]=""; + string statusTextFormat = lang.get("NetworkGameStatusWaiting"); + if(statusTextFormat == "" || statusTextFormat[0] == '?') { + statusTextFormat = "Waiting for players: %s"; + } + sprintf(szBuf1,statusTextFormat.c_str(),waitForHosts.c_str()); + + logger.add(szBuf, true, szBuf1); + + uint32 loadingStatus = nmls_NONE; + //send ready message after, so clients start delayed + for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + ConnectionSlot* connectionSlot= slots[i]; + if(connectionSlot != NULL && connectionSlot->isConnected() == true) { + switch(i) { + case 0: + loadingStatus |= nmls_PLAYER1_CONNECTED; + if(connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER1_READY; + } + break; + case 1: + loadingStatus |= nmls_PLAYER2_CONNECTED; + if(connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER2_READY; + } + break; + case 2: + loadingStatus |= nmls_PLAYER3_CONNECTED; + if(connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER3_READY; + } + break; + case 3: + loadingStatus |= nmls_PLAYER4_CONNECTED; + if(connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER4_READY; + } + break; + case 4: + loadingStatus |= nmls_PLAYER5_CONNECTED; + if(connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER5_READY; + } + break; + case 5: + loadingStatus |= nmls_PLAYER6_CONNECTED; + if(connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER6_READY; + } + break; + case 6: + loadingStatus |= nmls_PLAYER7_CONNECTED; + if(connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER7_READY; + } + break; + case 7: + loadingStatus |= nmls_PLAYER8_CONNECTED; + if(connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER8_READY; + } + break; + } + } + } + + // send loading status message + for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + ConnectionSlot* connectionSlot= slots[i]; + if(connectionSlot != NULL && connectionSlot->isConnected() == true) { + NetworkMessageLoadingStatus networkMessageLoadingStatus(loadingStatus); + connectionSlot->sendMessage(&networkMessageLoadingStatus); + } + } } } } Window::handleEvent(); } + + if(logger.getCancelLoading() == true) { + string sErr = lang.get("GameCancelledByUser"); + sendTextMessage(sErr,-1, true); + + quitGame(true); + + DisplayErrorMessage(sErr); + logger.setCancelLoading(false); + return; + } + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] PART B (telling client we are ready!\n",__FUNCTION__); try { //send ready message after, so clients start delayed