diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index 84d243b0..055b6f9e 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -4214,9 +4214,13 @@ void MenuStateCustomGame::updateNetworkSlots() { if(hasNetworkGameSettings() == true) { if(hasCheckedForUPNP == false) { - hasCheckedForUPNP = true; - serverInterface->getServerSocket()->NETdiscoverUPnPDevices(); + if(checkBoxPublishServer.getValue() == true || + this->headlessServerMode == true) { + + hasCheckedForUPNP = true; + serverInterface->getServerSocket()->NETdiscoverUPnPDevices(); + } } } else { diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 60e92844..fe57bde5 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -53,7 +53,7 @@ const int MAX_CLIENT_PAUSE_FOR_LAG_COUNT = 3; const int MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS = 1500; const int MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS = 30; -const int maxNetworkCommandListSendTimeWaitWhenAutoPaused = 4000; +const int MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS = 4000; ServerInterface::ServerInterface(bool publishEnabled, ClientLagCallbackInterface *clientLagCallbackInterface) : GameNetworkInterface() { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); @@ -1675,16 +1675,45 @@ void ServerInterface::updateKeyframe(int frameCount) { sendTextMessage(sMsg,-1, true,""); } - //broadcast commands + // broadcast commands + // If we have more than 0 commands to send, automatically broadcast them + bool sendBroadcastMessage = (networkMessageCommandList.getCommandCount() > 0); + if(sendBroadcastMessage == false) { - // Only send empty command list broadcasts when not paused - // or auto paused due to lag AND then only every X milliseconds - // where x = maxNetworkCommandListSendTimeWaitWhenAutoPaused - if(this->getClientsAutoPausedDueToLag() == false || - (this->getClientsAutoPausedDueToLag() == true && - (networkMessageCommandList.getCommandCount() > 0 || - lastBroadcastCommandsTimer.isStarted() == false || - lastBroadcastCommandsTimer.getMillis() >= maxNetworkCommandListSendTimeWaitWhenAutoPaused))) { + // Is auto pause due to lag NOT enabled + if(this->getClientsAutoPausedDueToLag() == false) { + + // ****NOTE: + // We always need to broadcast when not pause as clients + // look for broadcasts every network frame. + sendBroadcastMessage = true; + + // If network CRC checking enabled we turn on broadcasting always +// bool calculateNetworkCRC = false; +// if(isFlagType1BitEnabled(this->gameSettings.getFlagTypes1(),ft1_network_synch_checks) == true || +// isFlagType1BitEnabled(this->gameSettings.getFlagTypes1(),ft1_network_synch_checks_verbose) == true) { +// +// calculateNetworkCRC = true; +// } +// +// if(calculateNetworkCRC == true || +// (lastBroadcastCommandsTimer.isStarted() == false || +// lastBroadcastCommandsTimer.getMillis() >= MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS)) { +// +// sendBroadcastMessage = true; +// } + } + // Auto pause is enabled due to client lagging, only send empty command + // broadcasts every MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS + else if(this->getClientsAutoPausedDueToLag() == true && + (lastBroadcastCommandsTimer.isStarted() == false || + lastBroadcastCommandsTimer.getMillis() >= MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS)) { + + sendBroadcastMessage = true; + } + } + + if(sendBroadcastMessage == true) { if(lastBroadcastCommandsTimer.isStarted() == false) { lastBroadcastCommandsTimer.start(); @@ -2366,7 +2395,10 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) { shutdownFTPServer(); } - if(requiresUPNPTrigger == true) { + if((needToRepublishToMasterserver == true || + GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) && + requiresUPNPTrigger == true) { + this->getServerSocket()->NETdiscoverUPnPDevices(); } diff --git a/source/shared_lib/include/platform/posix/socket.h b/source/shared_lib/include/platform/posix/socket.h index 8b707635..f2dade58 100644 --- a/source/shared_lib/include/platform/posix/socket.h +++ b/source/shared_lib/include/platform/posix/socket.h @@ -328,6 +328,7 @@ public: static Mutex mutexUpnpdiscoverThread; static SDL_Thread *upnpdiscoverThread; + static bool cancelUpnpdiscoverThread; }; // ===================================================== diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index e7e6954f..514a58ea 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -75,6 +75,7 @@ int ServerSocket::maxPlayerCount = -1; int ServerSocket::externalPort = Socket::broadcast_portno; BroadCastClientSocketThread *ClientSocket::broadCastClientThread = NULL; SDL_Thread *ServerSocket::upnpdiscoverThread = NULL; +bool ServerSocket::cancelUpnpdiscoverThread = false; Mutex ServerSocket::mutexUpnpdiscoverThread; // // UPnP - Start @@ -2183,9 +2184,6 @@ ServerSocket::ServerSocket(bool basicMode) : Socket() { this->basicMode = basicMode; this->bindSpecificAddress = ""; //printf("SERVER SOCKET CONSTRUCTOR\n"); - //MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); - //ServerSocket::upnpdiscoverThread = NULL; - //safeMutexUPNP.ReleaseLock(); boundPort = 0; portBound = false; @@ -2205,22 +2203,17 @@ ServerSocket::~ServerSocket() { stopBroadCastThread(); if(this->basicMode == false) { - //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); - //printf("SERVER SOCKET DESTRUCTOR\n"); MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); if(ServerSocket::upnpdiscoverThread != NULL) { + + ServerSocket::cancelUpnpdiscoverThread = true; SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); ServerSocket::upnpdiscoverThread = NULL; + ServerSocket::cancelUpnpdiscoverThread = false; } safeMutexUPNP.ReleaseLock(); - //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); - - - //printf("In [%s::%s] Line: %d UPNP_Tools::enabledUPNP = %d\n",__FILE__,__FUNCTION__,__LINE__,UPNP_Tools::enabledUPNP); if (UPNP_Tools::enabledUPNP) { - //UPNP_Tools::NETremRedirects(ServerSocket::externalPort); UPNP_Tools::NETremRedirects(this->getExternalPort()); - //UPNP_Tools::enabledUPNP = false; } MutexSafeWrapper safeMutexUPNP1(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); @@ -2477,12 +2470,12 @@ Socket *ServerSocket::accept(bool errorOnFail) { void ServerSocket::NETdiscoverUPnPDevices() { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] UPNP - Start\n",__FILE__,__FUNCTION__,__LINE__); - //printf("SERVER SOCKET NETdiscoverUPnPDevices - START\n"); - //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); if(ServerSocket::upnpdiscoverThread != NULL) { + ServerSocket::cancelUpnpdiscoverThread = true; SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); ServerSocket::upnpdiscoverThread = NULL; + ServerSocket::cancelUpnpdiscoverThread = false; } // WATCH OUT! Because the thread takes void * as a parameter we MUST cast to the pointer type @@ -2562,7 +2555,7 @@ int UPNP_Tools::upnp_init(void *param) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] isUPNP = %d callback = %p\n",__FILE__,__FUNCTION__,__LINE__,UPNP_Tools::isUPNP,callback); - if(UPNP_Tools::isUPNP) { + if(UPNP_Tools::isUPNP == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Searching for UPnP devices for automatic port forwarding...\n"); int upnp_delay = 5000; @@ -2584,6 +2577,14 @@ int UPNP_Tools::upnp_init(void *param) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device search finished devlist = %p.\n",devlist); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP device search finished devlist = %p.\n",devlist); + if(ServerSocket::cancelUpnpdiscoverThread == true) { + if(devlist != NULL) { + freeUPNPDevlist(devlist); + } + devlist = NULL; + return result; + } + if (devlist) { dev = devlist; while (dev) { @@ -2632,6 +2633,14 @@ int UPNP_Tools::upnp_init(void *param) { devlist = NULL; } + if(ServerSocket::cancelUpnpdiscoverThread == true) { + if(devlist != NULL) { + freeUPNPDevlist(devlist); + } + devlist = NULL; + return result; + } + if (!urls.controlURL || urls.controlURL[0] == '\0') { snprintf(buf, 255,"controlURL not available, UPnP disabled"); if(callback) { @@ -2666,6 +2675,14 @@ int UPNP_Tools::upnp_init(void *param) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"No UPnP devices found.\n"); + if(ServerSocket::cancelUpnpdiscoverThread == true) { + if(devlist != NULL) { + freeUPNPDevlist(devlist); + } + devlist = NULL; + return result; + } + if(callback) { safeMutexUPNP.ReleaseLock(); callback->UPNPInitStatus(false); @@ -2677,6 +2694,14 @@ int UPNP_Tools::upnp_init(void *param) { snprintf(buf, 255,"UPnP detection routine disabled by user."); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP detection routine disabled by user.\n"); + if(ServerSocket::cancelUpnpdiscoverThread == true) { + if(devlist != NULL) { + freeUPNPDevlist(devlist); + } + devlist = NULL; + return result; + } + if(callback) { safeMutexUPNP.ReleaseLock(); callback->UPNPInitStatus(false); @@ -2696,14 +2721,14 @@ bool UPNP_Tools::upnp_add_redirect(int ports[2],bool mutexLock) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] upnp_add_redir(%d : %d)\n",__FILE__,__FUNCTION__,__LINE__,ports[0],ports[1]); if(mutexLock) { - //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); if(ServerSocket::upnpdiscoverThread != NULL) { + ServerSocket::cancelUpnpdiscoverThread = true; SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); ServerSocket::upnpdiscoverThread = NULL; + ServerSocket::cancelUpnpdiscoverThread = false; } safeMutexUPNP.ReleaseLock(); - //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); } MutexSafeWrapper safeMutexUPNP(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); @@ -2748,18 +2773,14 @@ bool UPNP_Tools::upnp_add_redirect(int ports[2],bool mutexLock) { void UPNP_Tools::upnp_rem_redirect(int ext_port) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] upnp_rem_redir(%d)\n",__FILE__,__FUNCTION__,__LINE__,ext_port); - //printf("SERVER SOCKET upnp_rem_redirect - START\n"); - - //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); if(ServerSocket::upnpdiscoverThread != NULL) { + ServerSocket::cancelUpnpdiscoverThread = true; SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); ServerSocket::upnpdiscoverThread = NULL; + ServerSocket::cancelUpnpdiscoverThread = false; } safeMutexUPNP.ReleaseLock(); - //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("In [%s::%s] Line: %d ext_port = %d urls.controlURL = [%s]\n",__FILE__,__FUNCTION__,__LINE__,ext_port,urls.controlURL); MutexSafeWrapper safeMutexUPNP1(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); if (urls.controlURL && urls.controlURL[0] != '\0') {