diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 620725d3c..e7add1c3d 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -122,7 +122,6 @@ ServerLobby::ServerLobby() : LobbyProtocol(NULL) } m_last_success_poll_time.store(StkTime::getRealTimeMs() + 30000); - m_waiting_players_counts.store(0); m_server_owner_id.store(-1); m_registered_for_once_only = false; m_has_created_server_id_file = false; @@ -432,7 +431,6 @@ void ServerLobby::asynchronousUpdate() if (allowJoinedPlayersWaiting() || (m_game_setup->isGrandPrix() && m_state.load() == WAITING_FOR_START_GAME)) { - updateWaitingPlayers(); // Only poll the STK server if this is a WAN server. if (NetworkConfig::get()->isWAN()) checkIncomingConnectionRequests(); @@ -500,9 +498,9 @@ void ServerLobby::asynchronousUpdate() { if (ServerConfig::m_owner_less) { - int player_size = - (int)STKHost::get()->updateConnectedPlayersInGame(); - if ((player_size >= ServerConfig::m_min_start_game_players || + unsigned players = 0; + STKHost::get()->updatePlayers(&players); + if (((int)players >= ServerConfig::m_min_start_game_players || m_game_setup->isGrandPrixStarted()) && m_timeout.load() == std::numeric_limits::max()) { @@ -510,7 +508,7 @@ void ServerLobby::asynchronousUpdate() (int64_t) (ServerConfig::m_start_game_counter * 1000.0f)); } - else if (player_size < ServerConfig::m_min_start_game_players && + else if ((int)players < ServerConfig::m_min_start_game_players && !m_game_setup->isGrandPrixStarted()) { resetPeersReady(); @@ -520,7 +518,7 @@ void ServerLobby::asynchronousUpdate() } if (m_timeout.load() < (int64_t)StkTime::getRealTimeMs() || (checkPeersReady() && - player_size >= ServerConfig::m_min_start_game_players)) + (int)players >= ServerConfig::m_min_start_game_players)) { resetPeersReady(); startSelection(); @@ -679,7 +677,7 @@ void ServerLobby::update(int ticks) resetServer(); } - STKHost::get()->updateConnectedPlayersInGame(); + STKHost::get()->updatePlayers(); if ((m_state.load() > WAITING_FOR_START_GAME || m_game_setup->isGrandPrixStarted()) && STKHost::get()->getPlayersInGame() == 0 && @@ -971,7 +969,8 @@ void ServerLobby::startSelection(const Event *event) if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FREE_FOR_ALL) { - unsigned max_player = STKHost::get()->updateConnectedPlayersInGame(); + unsigned max_player = 0; + STKHost::get()->updatePlayers(&max_player); auto it = m_available_kts.second.begin(); while (it != m_available_kts.second.end()) { @@ -1193,7 +1192,7 @@ void ServerLobby::checkIncomingConnectionRequests() request->addParameter("address", addr.getIP() ); request->addParameter("port", addr.getPort()); request->addParameter("current-players", - STKHost::get()->getPlayersInGame() + m_waiting_players_counts.load()); + STKHost::get()->getTotalPlayers()); request->addParameter("game-started", m_state.load() == WAITING_FOR_START_GAME ? 0 : 1); request->queue(); @@ -1680,8 +1679,9 @@ void ServerLobby::connectionRequested(Event* event) return; } - unsigned cur_players = STKHost::get()->updateConnectedPlayersInGame(); - if (cur_players + player_count + m_waiting_players_counts.load() > + unsigned total_players = 0; + STKHost::get()->updatePlayers(NULL, NULL, &total_players); + if (total_players + player_count > (unsigned)ServerConfig::m_server_max_players) { NetworkString *message = getNetworkString(2); @@ -1835,8 +1835,6 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr peer, if (game_started) { peer->setWaitingForGame(true); - for (auto& p : peer->getPlayerProfiles()) - m_waiting_players.push_back(p); updatePlayerList(); peer->sendPacket(message_ack); delete message_ack; @@ -2662,36 +2660,16 @@ bool ServerLobby::allowJoinedPlayersWaiting() const return !m_game_setup->isGrandPrix(); } // allowJoinedPlayersWaiting -//----------------------------------------------------------------------------- -void ServerLobby::updateWaitingPlayers() -{ - // addWaitingPlayersToGame below will be called by main thread in case - // resetServer - std::lock_guard lock(m_connection_mutex); - - m_waiting_players.erase(std::remove_if( - m_waiting_players.begin(), m_waiting_players.end(), [] - (const std::weak_ptr& npp)->bool - { - return npp.expired(); - }), m_waiting_players.end()); - m_waiting_players_counts.store((uint32_t)m_waiting_players.size()); -} // updateWaitingPlayers - //----------------------------------------------------------------------------- void ServerLobby::addWaitingPlayersToGame() { - if (m_waiting_players.empty()) - return; - for (auto& p : m_waiting_players) + auto all_profiles = STKHost::get()->getAllPlayerProfiles(); + for (auto& profile : all_profiles) { - auto npp = p.lock(); - if (!npp) + auto peer = profile->getPeer(); + if (!peer || !peer->isWaitingForGame() || !peer->isValidated()) continue; - auto peer = npp->getPeer(); - if (!peer) - continue; - uint32_t online_id = npp->getOnlineId(); + uint32_t online_id = profile->getOnlineId(); if (ServerConfig::m_ranked) { bool duplicated_ranked_player = @@ -2713,17 +2691,17 @@ void ServerLobby::addWaitingPlayersToGame() peer->setWaitingForGame(false); m_peers_ready[peer] = false; - Log::info("ServerLobby", "New player %s with online id %u from %s.", - StringUtils::wideToUtf8(npp->getName()).c_str(), - npp->getOnlineId(), peer->getAddress().toString().c_str()); + Log::info("ServerLobby", + "New player %s with online id %u from %s with %s.", + StringUtils::wideToUtf8(profile->getName()).c_str(), + profile->getOnlineId(), peer->getAddress().toString().c_str(), + peer->getUserVersion().c_str()); if (ServerConfig::m_ranked) { getRankingForPlayer(peer->getPlayerProfiles()[0]); } } - m_waiting_players.clear(); - m_waiting_players_counts.store(0); } // addWaitingPlayersToGame //----------------------------------------------------------------------------- diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 9ad5f5c42..1bbc5389e 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -145,10 +145,6 @@ private: NetworkString* m_result_ns; - std::vector > m_waiting_players; - - std::atomic m_waiting_players_counts; - std::atomic m_server_id_online; std::atomic m_difficulty; @@ -259,7 +255,6 @@ private: void checkRaceFinished(); std::pair getHitCaptureLimit(float num_karts); void configPeersStartTime(); - void updateWaitingPlayers(); void resetServer(); void addWaitingPlayersToGame(); void changeHandicap(Event* event); @@ -284,8 +279,6 @@ public: std::unique_lock acquireConnectionMutex() const { return std::unique_lock(m_connection_mutex); } bool waitingForPlayers() const; - uint32_t getWaitingPlayersCount() const - { return m_waiting_players_counts.load(); } virtual bool allPlayersReady() const OVERRIDE { return m_state.load() >= WAIT_FOR_RACE_STARTED; } virtual bool isRacing() const OVERRIDE { return m_state.load() == RACING; } diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index a3f0b97b7..ceb082dbc 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -289,6 +289,8 @@ STKHost::STKHost(bool server) void STKHost::init() { m_players_in_game.store(0); + m_players_waiting.store(0); + m_total_players.store(0); m_network_timer.store(StkTime::getRealTimeMs()); m_shutdown = false; m_authorised = false; @@ -1082,7 +1084,7 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket, s.addUInt32(ServerConfig::m_server_version); s.encodeString(name); s.addUInt8((uint8_t)ServerConfig::m_server_max_players); - s.addUInt8((uint8_t)(getPlayersInGame() + sl->getWaitingPlayersCount())); + s.addUInt8((uint8_t)getTotalPlayers()); s.addUInt16(m_private_port); s.addUInt8((uint8_t)sl->getDifficulty()); s.addUInt8((uint8_t)sl->getGameMode()); @@ -1260,7 +1262,7 @@ std::vector > std::unique_lock lock(m_peers_mutex); for (auto peer : m_peers) { - if (peer.second->isDisconnected()) + if (peer.second->isDisconnected() || !peer.second->isValidated()) continue; auto peer_profile = peer.second->getPlayerProfiles(); p.insert(p.end(), peer_profile.begin(), peer_profile.end()); @@ -1321,7 +1323,7 @@ std::pair STKHost::getAllPlayersTeamInfo() const } // getAllPlayersTeamInfo // ---------------------------------------------------------------------------- -/** \brief Get the players for starting a new game. +/** Get the players for starting a new game. * \return A vector containing pointers on the players profiles. */ std::vector > STKHost::getPlayersForNewGame() const @@ -1340,17 +1342,36 @@ std::vector > } // getPlayersForNewGame // ---------------------------------------------------------------------------- -uint32_t STKHost::updateConnectedPlayersInGame() +/** Update players count in server + * \param ingame store the in game players count now + * \param waiting store the waiting players count now + * \param total store the total players count now + */ +void STKHost::updatePlayers(unsigned* ingame, unsigned* waiting, + unsigned* total) { - uint32_t total = 0; + uint32_t ingame_players = 0; + uint32_t waiting_players = 0; + uint32_t total_players = 0; std::lock_guard lock(m_peers_mutex); for (auto& p : m_peers) { auto& stk_peer = p.second; - if (stk_peer->isWaitingForGame()) + if (!stk_peer->isValidated()) continue; - total += (uint32_t)stk_peer->getPlayerProfiles().size(); + if (stk_peer->isWaitingForGame()) + waiting_players += (uint32_t)stk_peer->getPlayerProfiles().size(); + else + ingame_players += (uint32_t)stk_peer->getPlayerProfiles().size(); + total_players += (uint32_t)stk_peer->getPlayerProfiles().size(); } - m_players_in_game.store(total); - return total; -} // updateConnectedPlayersInGame + m_players_in_game.store(ingame_players); + m_players_waiting.store(waiting_players); + m_total_players.store(total_players); + if (ingame) + *ingame = ingame_players; + if (waiting) + *waiting = waiting_players; + if (total) + *total = total_players; +} // updatePlayers diff --git a/src/network/stk_host.hpp b/src/network/stk_host.hpp index 249dbabde..d560247da 100644 --- a/src/network/stk_host.hpp +++ b/src/network/stk_host.hpp @@ -146,6 +146,10 @@ private: std::atomic m_players_in_game; + std::atomic m_players_waiting; + + std::atomic m_total_players; + std::atomic m_network_timer; std::unique_ptr m_nts; @@ -352,10 +356,16 @@ public: /* Return download speed in bytes per second. */ unsigned getDownloadSpeed() const { return m_download_speed.load(); } // ------------------------------------------------------------------------ - uint32_t updateConnectedPlayersInGame(); + void updatePlayers(unsigned* ingame = NULL, + unsigned* waiting = NULL, + unsigned* total = NULL); // ------------------------------------------------------------------------ uint32_t getPlayersInGame() const { return m_players_in_game.load(); } // ------------------------------------------------------------------------ + uint32_t getWaitingPlayers() const { return m_players_waiting.load(); } + // ------------------------------------------------------------------------ + uint32_t getTotalPlayers() const { return m_total_players.load(); } + // ------------------------------------------------------------------------ std::vector > getPlayersForNewGame() const; }; // class STKHost