From 6577762297bcecc6d76d1afec66c4f7d7a998266 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Fri, 30 Apr 2010 06:45:30 +0000 Subject: [PATCH] - Added a new pre-Cache thread for CRC value calculation - Added support in the client UI if multiple local LAN servers are discovered. --- source/glest_game/main/main.cpp | 164 ++++++++++++++++++ .../glest_game/menu/menu_state_join_game.cpp | 59 ++++--- source/glest_game/menu/menu_state_join_game.h | 3 + source/glest_game/network/network_message.h | 4 +- 4 files changed, 208 insertions(+), 22 deletions(-) diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 0993c661a..f2555db9b 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -29,6 +29,7 @@ #include "sound_renderer.h" #include "ImageReaders.h" #include "renderer.h" +#include "thread.h" #include "leak_dumper.h" @@ -100,6 +101,157 @@ public: } }; +class FileCRCPreCacheThread : public Thread +{ +private: + Mutex mutexRunning; + Mutex mutexQuit; + + bool quit; + bool running; + + void setRunningStatus(bool value); + void setQuitStatus(bool value); + +public: + FileCRCPreCacheThread(); + virtual void execute(); + void signalQuit(); + bool getQuitStatus(); + bool getRunningStatus(); + static void shutdownAndWait(FileCRCPreCacheThread *pThread); +}; + +FileCRCPreCacheThread::FileCRCPreCacheThread() { + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + setQuitStatus(false); + setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void FileCRCPreCacheThread::signalQuit() { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + setQuitStatus(true); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void FileCRCPreCacheThread::setQuitStatus(bool value) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + mutexQuit.p(); + quit = value; + mutexQuit.v(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +bool FileCRCPreCacheThread::getQuitStatus() { + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + bool retval = false; + mutexQuit.p(); + retval = quit; + mutexQuit.v(); + + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + return retval; +} + +bool FileCRCPreCacheThread::getRunningStatus() { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + bool retval = false; + mutexRunning.p(); + retval = running; + mutexRunning.v(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] running = %d\n",__FILE__,__FUNCTION__,__LINE__,retval); + + return retval; +} + +void FileCRCPreCacheThread::setRunningStatus(bool value) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] value = %d\n",__FILE__,__FUNCTION__,__LINE__,value); + + mutexRunning.p(); + running = value; + mutexRunning.v(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] running = %d\n",__FILE__,__FUNCTION__,__LINE__,value); +} + +void FileCRCPreCacheThread::execute() { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + setRunningStatus(true); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"FILE CRC PreCache thread is running\n"); + + try + { + Config &config = Config::getInstance(); + vector techDataPaths = config.getPathListForType(ptTechs); + //tech Tree listBox + vector techPaths; + findDirs(techDataPaths, techPaths); + if(techPaths.empty() == false) { + for(int idx = 0; idx < techPaths.size(); idx++) { + string &techPath = techPaths[idx]; + for(int idx2 = 0; idx2 < techPaths.size(); idx2++) { + string techName = techPaths[idx2]; + + printf("In [%s::%s Line: %d] caching CRC value for Tech [%s]\n",__FILE__,__FUNCTION__,__LINE__,techName.c_str()); + int32 techCRC = getFolderTreeContentsCheckSumRecursively(techDataPaths, string("/") + techName + string("/*"), ".xml", NULL); + printf("In [%s::%s Line: %d] cached CRC value for Tech [%s] is [%d]\n",__FILE__,__FUNCTION__,__LINE__,techName.c_str(),techCRC); + + if(getQuitStatus() == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + break; + } + sleep( 100 ); + } + if(getQuitStatus() == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + break; + } + } + } + } + catch(const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); + setRunningStatus(false); + } + catch(...) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__); + setRunningStatus(false); + } + + setRunningStatus(false); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"FILE CRC PreCache thread is exiting\n"); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void FileCRCPreCacheThread::shutdownAndWait(FileCRCPreCacheThread *pThread) { + if(pThread != NULL) { + pThread->signalQuit(); + for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 10; ) { + if(pThread->getRunningStatus() == false) { + break; + } + sleep(50); + //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__); + } +} + + // ===================================================== // class MainWindow // ===================================================== @@ -279,6 +431,8 @@ int glestMain(int argc, char** argv){ ExceptionHandler exceptionHandler; exceptionHandler.install( getCrashDumpFileName() ); + FileCRCPreCacheThread preCacheThread; + try{ Config &config = Config::getInstance(); @@ -339,6 +493,10 @@ int glestMain(int argc, char** argv){ gameInitialized = true; + if(config.getBool("AllowGameDataSynchCheck","false") == true) { + preCacheThread.start(); + } + // test //Shared::Platform::MessageBox(NULL,"Mark's test.","Test",0); //throw runtime_error("test!"); @@ -350,22 +508,28 @@ int glestMain(int argc, char** argv){ } } catch(const exception &e){ + FileCRCPreCacheThread::shutdownAndWait(&preCacheThread); //exceptionMessage(e); ExceptionHandler::handleRuntimeError(e.what()); } catch(const char *e){ //exceptionMessage(e); + FileCRCPreCacheThread::shutdownAndWait(&preCacheThread); ExceptionHandler::handleRuntimeError(e); } catch(const string &ex){ //exceptionMessage(e); + FileCRCPreCacheThread::shutdownAndWait(&preCacheThread); ExceptionHandler::handleRuntimeError(ex.c_str()); } catch(...){ //exceptionMessage(e); + FileCRCPreCacheThread::shutdownAndWait(&preCacheThread); ExceptionHandler::handleRuntimeError("Unknown error!"); } + FileCRCPreCacheThread::shutdownAndWait(&preCacheThread); + //SoundRenderer &soundRenderer= SoundRenderer::getInstance(); //soundRenderer.stopAllSounds(); diff --git a/source/glest_game/menu/menu_state_join_game.cpp b/source/glest_game/menu/menu_state_join_game.cpp index 98b5ab112..154884511 100644 --- a/source/glest_game/menu/menu_state_join_game.cpp +++ b/source/glest_game/menu/menu_state_join_game.cpp @@ -36,6 +36,9 @@ using namespace Shared::Util; // =============================== const int MenuStateJoinGame::newServerIndex= 0; +const int MenuStateJoinGame::newPrevServerIndex= 1; +const int MenuStateJoinGame::foundServersIndex= 2; + const string MenuStateJoinGame::serverFileName= "servers.ini"; @@ -73,6 +76,7 @@ MenuStateJoinGame::MenuStateJoinGame(Program *program, MainMenu *mainMenu, bool listBoxServerType.init(465, 490); listBoxServerType.pushBackItem(lang.get("ServerTypeNew")); listBoxServerType.pushBackItem(lang.get("ServerTypePrevious")); + listBoxServerType.pushBackItem(lang.get("ServerTypeFound")); //server label labelServer.init(330, 460); @@ -84,6 +88,9 @@ MenuStateJoinGame::MenuStateJoinGame(Program *program, MainMenu *mainMenu, bool listBoxServers.pushBackItem(servers.getKey(i)); } + // found servers listbox + listBoxFoundServers.init(465, 460); + //server ip labelServerIp.init(465, 460); @@ -101,8 +108,6 @@ MenuStateJoinGame::MenuStateJoinGame(Program *program, MainMenu *mainMenu, bool } labelServerPort.setText(port); - - labelStatus.init(330, 400); labelStatus.setText(""); @@ -135,10 +140,16 @@ MenuStateJoinGame::~MenuStateJoinGame() { void MenuStateJoinGame::DiscoveredServers(std::vector serverList) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + // Testing multi-server + //serverList.push_back("test1"); + //serverList.push_back("test2"); + // + buttonAutoFindServers.setEnabled(true); if(serverList.size() > 0) { string bestIPMatch = ""; std::vector localIPList = Socket::getLocalIPAddressList(); + for(int idx = 0; idx < serverList.size(); idx++) { bestIPMatch = serverList[idx]; SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] bestIPMatch = [%s] localIPList[0] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,bestIPMatch.c_str(),localIPList[0].c_str()); @@ -148,7 +159,14 @@ void MenuStateJoinGame::DiscoveredServers(std::vector serverList) { } labelServerIp.setText(bestIPMatch); - connectToServer(); + + if(serverList.size() > 1) { + listBoxServerType.setSelectedItemIndex(MenuStateJoinGame::foundServersIndex); + listBoxFoundServers.setItems(serverList); + } + else { + connectToServer(); + } } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } @@ -162,20 +180,24 @@ void MenuStateJoinGame::mouseClick(int x, int y, MouseButton mouseButton) NetworkManager &networkManager= NetworkManager::getInstance(); ClientInterface* clientInterface= networkManager.getClientInterface(); - if(!clientInterface->isConnected()){ + if(clientInterface->isConnected() == false) { //server type if(listBoxServerType.mouseClick(x, y)){ if(!listBoxServers.getText().empty()){ labelServerIp.setText(servers.getString(listBoxServers.getText())+"_"); } } - //server list - else if(listBoxServerType.getSelectedItemIndex()!=newServerIndex){ - if(listBoxServers.mouseClick(x, y)){ + else if(listBoxServerType.getSelectedItemIndex() == newPrevServerIndex){ + if(listBoxServers.mouseClick(x, y)) { labelServerIp.setText(servers.getString(listBoxServers.getText())+"_"); } } + else if(listBoxServerType.getSelectedItemIndex() == foundServersIndex){ + if(listBoxFoundServers.mouseClick(x, y)) { + labelServerIp.setText(listBoxFoundServers.getText()); + } + } } //return @@ -239,12 +261,15 @@ void MenuStateJoinGame::mouseMove(int x, int y, const MouseState *ms){ listBoxServerType.mouseMove(x, y); //hide-show options depending on the selection - if(listBoxServers.getSelectedItemIndex()==newServerIndex){ + if(listBoxServers.getSelectedItemIndex() == newServerIndex) { labelServerIp.mouseMove(x, y); } - else{ + else if(listBoxServers.getSelectedItemIndex() == newPrevServerIndex) { listBoxServers.mouseMove(x, y); } + else { + listBoxFoundServers.mouseMove(x, y); + } } void MenuStateJoinGame::render(){ @@ -261,13 +286,15 @@ void MenuStateJoinGame::render(){ renderer.renderButton(&buttonAutoFindServers); renderer.renderListBox(&listBoxServerType); - if(listBoxServerType.getSelectedItemIndex()==newServerIndex){ + if(listBoxServerType.getSelectedItemIndex() == newServerIndex) { renderer.renderLabel(&labelServerIp); } - else - { + else if(listBoxServerType.getSelectedItemIndex() == newPrevServerIndex) { renderer.renderListBox(&listBoxServers); } + else { + renderer.renderListBox(&listBoxFoundServers); + } renderer.renderChatManager(&chatManager); renderer.renderConsole(&console); @@ -308,10 +335,6 @@ void MenuStateJoinGame::update() { label = label + " techtree"; } - //if(clientInterface->getNetworkGameDataSynchCheckOkFogOfWar() == false) - //{ - // label = label + " FogOfWar == false"; - //} } else if(clientInterface->getAllowGameDataSynchCheck() == true) { @@ -344,10 +367,6 @@ void MenuStateJoinGame::update() { label = label + " techtree"; } - //if(clientInterface->getNetworkGameDataSynchCheckOkFogOfWar() == false) - //{ - // label = label + " FogOfWar == false"; - //} } else if(clientInterface->getAllowGameDataSynchCheck() == true) { diff --git a/source/glest_game/menu/menu_state_join_game.h b/source/glest_game/menu/menu_state_join_game.h index 5a523a8fa..158efcf9e 100644 --- a/source/glest_game/menu/menu_state_join_game.h +++ b/source/glest_game/menu/menu_state_join_game.h @@ -31,6 +31,8 @@ class NetworkMessageIntro; class MenuStateJoinGame: public MenuState, public DiscoveredServersInterface { private: static const int newServerIndex; + static const int newPrevServerIndex; + static const int foundServersIndex; static const string serverFileName; private: @@ -44,6 +46,7 @@ private: GraphicLabel labelInfo; GraphicListBox listBoxServerType; GraphicListBox listBoxServers; + GraphicListBox listBoxFoundServers; GraphicLabel labelServerPort; GraphicLabel labelServerPortLabel; diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index 2e9c0b8c8..1e0bcc2bf 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -72,8 +72,8 @@ protected: class NetworkMessageIntro: public NetworkMessage{ private: - static const int maxVersionStringSize= 64; - static const int maxNameSize= 16; + static const int maxVersionStringSize= 128; + static const int maxNameSize= 32; private: struct Data{