From 176af22c8d20736b17af9f394222fe419e076d3c Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 14 Dec 2018 19:22:59 +0800 Subject: [PATCH] Add the framework for displaying estimated game started info --- src/modes/world.hpp | 13 ++++++-- src/network/protocols/lobby_protocol.cpp | 1 + src/network/protocols/lobby_protocol.hpp | 28 +++++++++++++++- src/network/protocols/server_lobby.cpp | 6 +++- src/network/stk_host.cpp | 33 +++++++++++++++++-- .../online/networking_lobby.cpp | 26 +++++++++++++-- 6 files changed, 98 insertions(+), 9 deletions(-) diff --git a/src/modes/world.hpp b/src/modes/world.hpp index 7c9721dfc..d8562799f 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -25,6 +25,7 @@ * battle, etc.) */ +#include #include #include #include @@ -359,9 +360,17 @@ public: // ------------------------------------------------------------------------ /** Set the network mode (true if networked) */ void setNetworkWorld(bool is_networked) { m_is_network_world = is_networked; } - + // ------------------------------------------------------------------------ bool isNetworkWorld() const { return m_is_network_world; } - + // ------------------------------------------------------------------------ + /** Used by server to get the current started game progress in either or + * both remaining time or progress in percent. uint32_t max for either or + * both if not available. */ + virtual std::pair getGameStartedProgress() const + { + return std::make_pair(std::numeric_limits::max(), + std::numeric_limits::max()); + } }; // World #endif diff --git a/src/network/protocols/lobby_protocol.cpp b/src/network/protocols/lobby_protocol.cpp index a837a9f3f..c58aa0418 100644 --- a/src/network/protocols/lobby_protocol.cpp +++ b/src/network/protocols/lobby_protocol.cpp @@ -36,6 +36,7 @@ std::weak_ptr LobbyProtocol::m_lobby; LobbyProtocol::LobbyProtocol(CallbackObject* callback_object) : Protocol(PROTOCOL_LOBBY_ROOM, callback_object) { + resetGameStartedProgress(); m_game_setup = new GameSetup(); } // LobbyProtocol diff --git a/src/network/protocols/lobby_protocol.hpp b/src/network/protocols/lobby_protocol.hpp index f09fbbc7e..bcb9d8353 100644 --- a/src/network/protocols/lobby_protocol.hpp +++ b/src/network/protocols/lobby_protocol.hpp @@ -24,6 +24,7 @@ class GameSetup; class NetworkPlayerProfile; +#include #include #include #include @@ -82,6 +83,14 @@ protected: static std::weak_ptr m_lobby; + /** Estimated current started game remaining time, + * uint32_t max if not available. */ + std::atomic m_estimated_remaining_time; + + /** Estimated current started game progress in 0-100%, + * uint32_t max if not available. */ + std::atomic m_estimated_progress; + /** Stores data about the online game to play. */ GameSetup* m_game_setup; @@ -130,7 +139,24 @@ public: virtual bool allPlayersReady() const = 0; virtual bool isRacing() const = 0; GameSetup* getGameSetup() const { return m_game_setup; } - + // ------------------------------------------------------------------------ + std::pair getGameStartedProgress() const + { + return std::make_pair(m_estimated_remaining_time.load(), + m_estimated_progress.load()); + } + // ------------------------------------------------------------------------ + void setGameStartedProgress(const std::pair& p) + { + m_estimated_remaining_time.store(p.first); + m_estimated_progress.store(p.second); + } + // ------------------------------------------------------------------------ + void resetGameStartedProgress() + { + m_estimated_remaining_time.store(std::numeric_limits::max()); + m_estimated_progress.store(std::numeric_limits::max()); + } }; // class LobbyProtocol #endif // LOBBY_PROTOCOL_HPP diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 5125bde38..889cd05f8 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -616,13 +616,13 @@ void ServerLobby::asynchronousUpdate() */ void ServerLobby::update(int ticks) { + World* w = World::getWorld(); int sec = ServerConfig::m_kick_idle_player_seconds; if (NetworkConfig::get()->isWAN() && sec > 0 && m_state.load() >= WAIT_FOR_WORLD_LOADED && m_state.load() <= RACING && m_server_has_loaded_world.load() == true) { auto players = m_game_setup->getConnectedPlayers(true/*same_offset*/); - World* w = World::getWorld(); for (unsigned i = 0; i < players.size(); i++) { if (!players[i]) @@ -640,6 +640,10 @@ void ServerLobby::update(int ticks) } } } + if (w) + setGameStartedProgress(w->getGameStartedProgress()); + else + resetGameStartedProgress(); // Reset server to initial state if no more connected players if (m_waiting_for_reset) diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index e2a1b6d51..a002be8ee 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -796,6 +796,17 @@ void STKHost::mainLoop() ping_packet.addUInt8((uint8_t)m_peer_pings.getData().size()); for (auto& p : m_peer_pings.getData()) ping_packet.addUInt32(p.first).addUInt32(p.second); + if (sl) + { + auto progress = sl->getGameStartedProgress(); + ping_packet.addUInt32(progress.first) + .addUInt32(progress.second); + } + else + { + ping_packet.addUInt32(std::numeric_limits::max()) + .addUInt32(std::numeric_limits::max()); + } ping_packet.getBuffer().insert( ping_packet.getBuffer().begin(), g_ping_packet.begin(), g_ping_packet.end()); @@ -866,12 +877,12 @@ void STKHost::mainLoop() bool need_ping_update = false; while (enet_host_service(host, &event, 10) != 0) { + auto lp = LobbyProtocol::get(); if (!is_server && last_ping_time_update_for_client < StkTime::getRealTimeMs()) { last_ping_time_update_for_client = StkTime::getRealTimeMs() + 2000; - auto lp = LobbyProtocol::get(); if (lp && lp->isRacing()) { auto p = getServerPeerForClient(); @@ -950,7 +961,20 @@ void STKHost::mainLoop() const uint32_t client_ping = peer_pings.find(m_host_id) != peer_pings.end() ? peer_pings.at(m_host_id) : 0; - + uint32_t remaining_time = + std::numeric_limits::max(); + uint32_t progress = + std::numeric_limits::max(); + try + { + remaining_time = ping_packet.getUInt32(); + progress = ping_packet.getUInt32(); + } + catch (std::exception& e) + { + // For old server + Log::debug("STKHost", "%s", e.what()); + } if (client_ping > 0) { assert(m_nts); @@ -963,6 +987,11 @@ void STKHost::mainLoop() m_peer_pings.unlock(); m_client_ping.store(client_ping, std::memory_order_relaxed); + if (lp) + { + lp->setGameStartedProgress( + std::make_pair(remaining_time, progress)); + } } } enet_packet_destroy(event.packet); diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index d5148d770..82803fe2b 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -255,9 +255,29 @@ void NetworkingLobby::onUpdate(float delta) { m_start_button->setVisible(false); m_timeout_message->setVisible(true); - //I18N: In the networking lobby, show when player is required to wait - //before the current game finish - core::stringw msg = _("Please wait for current game to end."); + auto progress = cl->getGameStartedProgress(); + core::stringw msg; + if (progress.first != std::numeric_limits::max()) + { + //I18N: In the networking lobby, show when player is required to + //wait before the current game finish with remaining time + msg = _("Please wait for current game to end, " + "estimated remaining time: %s.", + StringUtils::timeToString((float)progress.first).c_str()); + } + else if (progress.second != std::numeric_limits::max()) + { + //I18N: In the networking lobby, show when player is required to + //wait before the current game finish with progress in percent + msg = _("Please wait for current game to end, " + "estimated progress: %d%.", progress.second); + } + else + { + //I18N: In the networking lobby, show when player is required to + //wait before the current game finish + msg = _("Please wait for current game to end."); + } m_timeout_message->setText(msg, false); core::stringw total_msg; for (auto& string : m_server_info)