Index: binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.js =================================================================== --- binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.js +++ binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.js @@ -206,6 +206,9 @@ case "netwarn": break; + case "clients-loading": + break; + default: error("Unrecognised net message type: " + message.type); } Index: source/network/NetServer.h =================================================================== --- source/network/NetServer.h +++ source/network/NetServer.h @@ -271,10 +271,9 @@ /** * Checks if all clients have finished loading. * If so informs the clients about that and change the server state. - * - * Returns if all clients finished loading. + * Otherwise informs the clients who has and who has not finished loading. */ - bool CheckGameLoadStatus(CNetServerSession* changedSession); + void CheckGameLoadStatus(CNetServerSession* changedSession); void ConstructPlayerAssignmentMessage(CPlayerAssignmentMessage& message); Index: source/network/NetServer.cpp =================================================================== --- source/network/NetServer.cpp +++ source/network/NetServer.cpp @@ -517,8 +517,7 @@ event.peer->data = NULL; } - if (m_State == SERVER_STATE_LOADING) - CheckGameLoadStatus(NULL); + CheckGameLoadStatus(nullptr); break; } @@ -1272,26 +1271,7 @@ loadedSession->SetLongTimeout(false); - // We're in the loading state, so wait until every client has loaded - // before starting the game - ENSURE(server.m_State == SERVER_STATE_LOADING); - if (server.CheckGameLoadStatus(loadedSession)) - return true; - - CClientsLoadingMessage message; - // We always send all GUIDs of clients in the loading state - // so that we don't have to bother about switching GUI pages - for (CNetServerSession* session : server.m_Sessions) - if (session->GetCurrState() != NSS_INGAME && loadedSession->GetGUID() != session->GetGUID()) - { - CClientsLoadingMessage::S_m_Clients client; - client.m_GUID = session->GetGUID(); - message.m_Clients.push_back(client); - } - - // Send to the client who has loaded the game but did not reach the NSS_INGAME state yet - loadedSession->SendMessage(&message); - server.Broadcast(&message, { NSS_INGAME }); + server.CheckGameLoadStatus(loadedSession); return true; } @@ -1440,21 +1420,34 @@ return true; } -bool CNetServerWorker::CheckGameLoadStatus(CNetServerSession* changedSession) +void CNetServerWorker::CheckGameLoadStatus(CNetServerSession* loadedSession) { + if (m_State != SERVER_STATE_LOADING) + return; + + // Find out which players are still in the loading screen + CClientsLoadingMessage loadingMessage; for (const CNetServerSession* session : m_Sessions) - if (session != changedSession && session->GetCurrState() != NSS_INGAME) - return false; + if (session != loadedSession && session->GetCurrState() != NSS_INGAME) + { + CClientsLoadingMessage::S_m_Clients client; + client.m_GUID = session->GetGUID(); + loadingMessage.m_Clients.push_back(client); + } - // Inform clients that everyone has loaded the map and that the game can start - CLoadedGameMessage loaded; - loaded.m_CurrentTurn = 0; + // Notice the loadedSession is still in the NSS_PREGAME state + if (loadingMessage.m_Clients.empty()) + { + // Inform clients that everyone has loaded the map and that the game can start + CLoadedGameMessage loaded; + loaded.m_CurrentTurn = 0; - // Notice the changedSession is still in the NSS_PREGAME state - Broadcast(&loaded, { NSS_PREGAME, NSS_INGAME }); + Broadcast(&loaded, { NSS_PREGAME, NSS_INGAME }); - m_State = SERVER_STATE_INGAME; - return true; + m_State = SERVER_STATE_INGAME; + } + else + Broadcast(&loadingMessage, { NSS_PREGAME, NSS_INGAME }); } void CNetServerWorker::StartGame()