Index: source/network/NetClient.h =================================================================== --- source/network/NetClient.h +++ source/network/NetClient.h @@ -38,14 +38,32 @@ // NetClient session FSM states enum { + // The enet connection to the server was not established yet. NCS_UNCONNECTED, + + // The client established the connection and waits for the server to send the protcol and engine version. NCS_CONNECT, + + // Protocol and engine version are exchanged. NCS_HANDSHAKE, + + // The client needs to send its username and possibly password. NCS_AUTHENTICATE, - NCS_INITIAL_GAMESETUP, - NCS_PREGAME, + + // The client was authenticated, received a unique ID for the turnmanager and was informed if a rejoin needs to be performed. + // It now waits for the server to send the gamesettings in order to reveal the gamesetup page or start the rejoin. + NCS_AUTHENTICATED, + + // The client is in the match setup where the map settings and player assignments are chosen. + NCS_GAMESETUP, + + // The game was started and the client is in the loading screen. NCS_LOADING, + + // The client is rejoining a running match. NCS_JOIN_SYNCING, + + // The client is simulating the current match and can send commands. NCS_INGAME }; @@ -232,7 +250,7 @@ static bool OnHandshake(void* context, CFsmEvent* event); static bool OnHandshakeResponse(void* context, CFsmEvent* event); static bool OnAuthenticateRequest(void* context, CFsmEvent* event); - static bool OnAuthenticate(void* context, CFsmEvent* event); + static bool OnAuthenticateResult(void* context, CFsmEvent* event); static bool OnChat(void* context, CFsmEvent* event); static bool OnReady(void* context, CFsmEvent* event); static bool OnGameSetup(void* context, CFsmEvent* event); Index: source/network/NetClient.cpp =================================================================== --- source/network/NetClient.cpp +++ source/network/NetClient.cpp @@ -90,19 +90,19 @@ AddTransition(NCS_HANDSHAKE, (uint)NMT_SERVER_HANDSHAKE_RESPONSE, NCS_AUTHENTICATE, (void*)&OnHandshakeResponse, context); AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE, NCS_AUTHENTICATE, (void*)&OnAuthenticateRequest, context); - AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE_RESULT, NCS_INITIAL_GAMESETUP, (void*)&OnAuthenticate, context); + AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE_RESULT, NCS_AUTHENTICATED, (void*)&OnAuthenticateResult, context); - AddTransition(NCS_INITIAL_GAMESETUP, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context); + AddTransition(NCS_AUTHENTICATED, (uint)NMT_GAME_SETUP, NCS_GAMESETUP, (void*)&OnGameSetup, context); - AddTransition(NCS_PREGAME, (uint)NMT_CHAT, NCS_PREGAME, (void*)&OnChat, context); - AddTransition(NCS_PREGAME, (uint)NMT_READY, NCS_PREGAME, (void*)&OnReady, context); - AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context); - AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, (void*)&OnPlayerAssignment, context); - AddTransition(NCS_PREGAME, (uint)NMT_KICKED, NCS_PREGAME, (void*)&OnKicked, context); - AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_PREGAME, (void*)&OnClientTimeout, context); - AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_PREGAME, (void*)&OnClientPerformance, context); - AddTransition(NCS_PREGAME, (uint)NMT_GAME_START, NCS_LOADING, (void*)&OnGameStart, context); - AddTransition(NCS_PREGAME, (uint)NMT_JOIN_SYNC_START, NCS_JOIN_SYNCING, (void*)&OnJoinSyncStart, context); + AddTransition(NCS_GAMESETUP, (uint)NMT_CHAT, NCS_GAMESETUP, (void*)&OnChat, context); + AddTransition(NCS_GAMESETUP, (uint)NMT_READY, NCS_GAMESETUP, (void*)&OnReady, context); + AddTransition(NCS_GAMESETUP, (uint)NMT_GAME_SETUP, NCS_GAMESETUP, (void*)&OnGameSetup, context); + AddTransition(NCS_GAMESETUP, (uint)NMT_PLAYER_ASSIGNMENT, NCS_GAMESETUP, (void*)&OnPlayerAssignment, context); + AddTransition(NCS_GAMESETUP, (uint)NMT_KICKED, NCS_GAMESETUP, (void*)&OnKicked, context); + AddTransition(NCS_GAMESETUP, (uint)NMT_CLIENT_TIMEOUT, NCS_GAMESETUP, (void*)&OnClientTimeout, context); + AddTransition(NCS_GAMESETUP, (uint)NMT_CLIENT_PERFORMANCE, NCS_GAMESETUP, (void*)&OnClientPerformance, context); + AddTransition(NCS_GAMESETUP, (uint)NMT_GAME_START, NCS_LOADING, (void*)&OnGameStart, context); + AddTransition(NCS_GAMESETUP, (uint)NMT_JOIN_SYNC_START, NCS_JOIN_SYNCING, (void*)&OnJoinSyncStart, context); AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CHAT, NCS_JOIN_SYNCING, (void*)&OnChat, context); AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_SETUP, NCS_JOIN_SYNCING, (void*)&OnGameSetup, context); @@ -554,7 +554,7 @@ return true; } -bool CNetClient::OnAuthenticateRequest(void* context, CFsmEvent* event) +bool CNetClient::OnAuthenticateResultRequest(void* context, CFsmEvent* event) { ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE); @@ -563,7 +563,7 @@ return true; } -bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event) +bool CNetClient::OnAuthenticateResult(void* context, CFsmEvent* event) { ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE_RESULT); Index: source/network/NetServer.h =================================================================== --- source/network/NetServer.h +++ source/network/NetServer.h @@ -43,15 +43,16 @@ // The worker thread has not been started. SERVER_STATE_UNCONNECTED, - // The server is open and accepting connections. This is the screen where - // rules are set up by the operator and where players join and select civs - // and stuff. - SERVER_STATE_PREGAME, + // The server has been initialized and is listening for connections. + // Now the map settings and player assignements are setup by the controller. + SERVER_STATE_GAMESETUP, - // All the hosts are connected and are loading the game + // The gamesetup was completed, the game was started and now the map is loading. + // At least one of the clients didn't finish the loading screen yet. SERVER_STATE_LOADING, - // The one with all the killing ;-) + // All clients finished the loading screen. + // Players can send simulation commands while the game advances. SERVER_STATE_INGAME, // The game is over and someone has won. Players might linger to chat or @@ -68,19 +69,20 @@ NSS_UNCONNECTED, // The client has just connected and we're waiting for its handshake message, - // to agree on the protocol version + // to agree on the protocol version. NSS_HANDSHAKE, - // The client has handshook and we're waiting for its lobby authentication message - NSS_LOBBY_AUTHENTICATE, - - // The client has handshook and we're waiting for its authentication message, - // to find its name and check its password etc + // The client uses a correct protocol version, but didn't authenticate yet. + // The server assigned the unique identifier GUID to the client and sent that to the client. + // The server informed the client that lobby authentication is not enabled. + // The server now waits for the clients authentication message to find its username and optionally check the server password. NSS_AUTHENTICATE, - // The client has fully joined, and is in the pregame setup stage - // or is loading the game. - // Server must be in SERVER_STATE_PREGAME or SERVER_STATE_LOADING. + // Same as NSS_AUTHENTICATE, but lobby authentication is enabled. + NSS_LOBBY_AUTHENTICATE, + + // The client has authenticated and is either in the gamesetup stage or is loading the game. + // Server must be in SERVER_STATE_GAMESETUP or SERVER_STATE_LOADING. NSS_PREGAME, // The client has authenticated but the game was already started, Index: source/network/NetServer.cpp =================================================================== --- source/network/NetServer.cpp +++ source/network/NetServer.cpp @@ -128,6 +128,8 @@ */ CNetServerWorker::CNetServerWorker(bool useLobbyAuth, int autostartPlayers) : + m_WorkerThread(nullptr), + m_UPnPThread(nullptr), m_AutostartPlayers(autostartPlayers), m_LobbyAuth(useLobbyAuth), m_Shutdown(false), @@ -194,7 +196,7 @@ if (CProfileViewer::IsInitialised()) g_ProfileViewer.AddRootTable(m_Stats); - m_State = SERVER_STATE_PREGAME; + m_State = SERVER_STATE_GAMESETUP; // Launch the worker thread int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this); @@ -382,7 +384,7 @@ break; // Implement autostart mode - if (m_State == SERVER_STATE_PREGAME && (int)m_PlayerAssignments.size() == m_AutostartPlayers) + if (m_State == SERVER_STATE_GAMESETUP && (int)m_PlayerAssignments.size() == m_AutostartPlayers) StartGame(); // Update profiler stats @@ -594,7 +596,7 @@ for (size_t j = 0; j < m_Sessions.size(); ++j) { if (i != j && ( - (m_Sessions[j]->GetCurrState() == NSS_PREGAME && m_State == SERVER_STATE_PREGAME) || + (m_Sessions[j]->GetCurrState() == NSS_PREGAME && m_State == SERVER_STATE_GAMESETUP) || m_Sessions[j]->GetCurrState() == NSS_INGAME)) { m_Sessions[j]->SendMessage(message); @@ -934,7 +936,7 @@ return true; } -bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event) +bool CNetServerWorker::OnAuthenticateRequest(void* context, CFsmEvent* event) { ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE); @@ -995,7 +997,7 @@ bool isRejoining = false; bool serverFull = false; - if (server.m_State == SERVER_STATE_PREGAME) + if (server.m_State == SERVER_STATE_GAMESETUP) { // Don't check for maxObservers in the gamesetup, as we don't know yet who will be assigned serverFull = server.m_Sessions.size() >= MAX_CLIENTS; Index: source/network/NetSession.cpp =================================================================== --- source/network/NetSession.cpp +++ source/network/NetSession.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -84,7 +84,7 @@ // Prevent the local client of the host from timing out too quickly. #if (ENET_VERSION >= ENET_VERSION_CREATE(1, 3, 4)) if (isLocalClient) - enet_peer_timeout(peer, 1, MAXIMUM_HOST_TIMEOUT, MAXIMUM_HOST_TIMEOUT); + enet_peer_timeout(peer, 0, MAXIMUM_HOST_TIMEOUT, MAXIMUM_HOST_TIMEOUT); #endif m_Stats = new CNetStatsTable(m_Server); @@ -203,7 +203,7 @@ CNetServerSession::CNetServerSession(CNetServerWorker& server, ENetPeer* peer) : - m_Server(server), m_FileTransferer(this), m_Peer(peer) + m_Server(server), m_FileTransferer(this), m_Peer(peer), m_IsLocalClient(false), m_HostID(0) { } Index: source/network/tests/test_Net.h =================================================================== --- source/network/tests/test_Net.h +++ source/network/tests/test_Net.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -83,7 +83,7 @@ for (size_t j = 0; j < clients.size(); ++j) clients[j]->Poll(); - if (clients_are_all(clients, NCS_PREGAME)) + if (clients_are_all(clients, NCS_GAMESETUP)) break; if (i > 20) @@ -281,7 +281,7 @@ { debug_printf("[%u]\n", client2B.GetCurrState()); client2B.Poll(); - if (client2B.GetCurrState() == NCS_PREGAME) + if (client2B.GetCurrState() == NCS_GAMESETUP) break; if (client2B.GetCurrState() == NCS_UNCONNECTED)