Add the framework for displaying estimated game started info

This commit is contained in:
Benau 2018-12-14 19:22:59 +08:00
parent 8f5ee309a8
commit 176af22c8d
6 changed files with 98 additions and 9 deletions

View File

@ -25,6 +25,7 @@
* battle, etc.)
*/
#include <limits>
#include <map>
#include <memory>
#include <vector>
@ -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<uint32_t, uint32_t> getGameStartedProgress() const
{
return std::make_pair(std::numeric_limits<uint32_t>::max(),
std::numeric_limits<uint32_t>::max());
}
}; // World
#endif

View File

@ -36,6 +36,7 @@ std::weak_ptr<LobbyProtocol> LobbyProtocol::m_lobby;
LobbyProtocol::LobbyProtocol(CallbackObject* callback_object)
: Protocol(PROTOCOL_LOBBY_ROOM, callback_object)
{
resetGameStartedProgress();
m_game_setup = new GameSetup();
} // LobbyProtocol

View File

@ -24,6 +24,7 @@
class GameSetup;
class NetworkPlayerProfile;
#include <atomic>
#include <cassert>
#include <memory>
#include <thread>
@ -82,6 +83,14 @@ protected:
static std::weak_ptr<LobbyProtocol> m_lobby;
/** Estimated current started game remaining time,
* uint32_t max if not available. */
std::atomic<uint32_t> m_estimated_remaining_time;
/** Estimated current started game progress in 0-100%,
* uint32_t max if not available. */
std::atomic<uint32_t> 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<uint32_t, uint32_t> getGameStartedProgress() const
{
return std::make_pair(m_estimated_remaining_time.load(),
m_estimated_progress.load());
}
// ------------------------------------------------------------------------
void setGameStartedProgress(const std::pair<uint32_t, uint32_t>& p)
{
m_estimated_remaining_time.store(p.first);
m_estimated_progress.store(p.second);
}
// ------------------------------------------------------------------------
void resetGameStartedProgress()
{
m_estimated_remaining_time.store(std::numeric_limits<uint32_t>::max());
m_estimated_progress.store(std::numeric_limits<uint32_t>::max());
}
}; // class LobbyProtocol
#endif // LOBBY_PROTOCOL_HPP

View File

@ -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)

View File

@ -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<uint32_t>::max())
.addUInt32(std::numeric_limits<uint32_t>::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<LobbyProtocol>();
if (!is_server &&
last_ping_time_update_for_client < StkTime::getRealTimeMs())
{
last_ping_time_update_for_client =
StkTime::getRealTimeMs() + 2000;
auto lp = LobbyProtocol::get<LobbyProtocol>();
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<uint32_t>::max();
uint32_t progress =
std::numeric_limits<uint32_t>::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);

View File

@ -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<uint32_t>::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<uint32_t>::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)