diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 20c152e86..83a6273db 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -94,6 +94,7 @@ ClientLobby::ClientLobby(const TransportAddress& a, std::shared_ptr s) _("Bad network connection is detected."); m_first_connect = true; m_spectator = false; + m_server_live_joinable = false; } // ClientLobby //----------------------------------------------------------------------------- @@ -664,9 +665,7 @@ void ClientLobby::handleServerInfo(Event* event) } bool server_config = data.getUInt8() == 1; NetworkingLobby::getInstance()->toggleServerConfigButton(server_config); - bool live_join_spectator = data.getUInt8() == 1; - NetworkingLobby::getInstance() - ->toggleServerLiveJoinable(live_join_spectator); + m_server_live_joinable = data.getUInt8() == 1; } // handleServerInfo //----------------------------------------------------------------------------- @@ -683,42 +682,40 @@ void ClientLobby::updatePlayerList(Event* event) m_waiting_for_game = waiting; unsigned player_count = data.getUInt8(); - std::vector > players; core::stringw total_players; + m_lobby_players.clear(); for (unsigned i = 0; i < player_count; i++) { - std::tuple pl; - uint32_t host_id = data.getUInt32(); - uint32_t online_id = data.getUInt32(); + LobbyPlayer lp = {}; + lp.m_host_id = data.getUInt32(); + lp.m_online_id = data.getUInt32(); uint8_t local_id = data.getUInt8(); - std::get<0>(pl) = host_id; - std::get<1>(pl) = online_id; - std::get<2>(pl) = local_id; - data.decodeStringW(&std::get<3>(pl)); - total_players += std::get<3>(pl); + lp.m_difficulty = PLAYER_DIFFICULTY_NORMAL; + lp.m_local_player_id = local_id; + data.decodeStringW(&lp.m_user_name); + total_players += lp.m_user_name; bool is_peer_waiting_for_game = data.getUInt8() == 1; bool is_peer_server_owner = data.getUInt8() == 1; // icon to be used, see NetworkingLobby::loadedFromFile - std::get<4>(pl) = is_peer_server_owner ? 0 : - std::get<1>(pl) != 0 /*if online account*/ ? 1 : 2; + lp.m_icon_id = is_peer_server_owner ? 0 : + lp.m_online_id != 0 /*if online account*/ ? 1 : 2; if (waiting && !is_peer_waiting_for_game) - std::get<4>(pl) = 3; - PerPlayerDifficulty d = (PerPlayerDifficulty)data.getUInt8(); - std::get<6>(pl) = d; - if (d == PLAYER_DIFFICULTY_HANDICAP) - std::get<3>(pl) = _("%s (handicapped)", std::get<3>(pl)); - std::get<5>(pl) = (KartTeam)data.getUInt8(); + lp.m_icon_id = 3; + lp.m_difficulty = (PerPlayerDifficulty)data.getUInt8(); + if (lp.m_difficulty == PLAYER_DIFFICULTY_HANDICAP) + { + lp.m_user_name = _("%s (handicapped)", lp.m_user_name); + } + lp.m_kart_team = (KartTeam)data.getUInt8(); bool ready = data.getUInt8() == 1; if (ready) - std::get<4>(pl) = 4; - if (host_id == STKHost::get()->getMyHostId()) + lp.m_icon_id = 4; + if (lp.m_host_id == STKHost::get()->getMyHostId()) { auto& local_players = NetworkConfig::get()->getNetworkPlayers(); - std::get<2>(local_players.at(local_id)) = d; + std::get<2>(local_players.at(local_id)) = lp.m_difficulty; } - players.push_back(pl); + m_lobby_players.push_back(lp); } // Notification sound for new player @@ -727,7 +724,7 @@ void ClientLobby::updatePlayerList(Event* event) SFXManager::get()->quickSound("energy_bar_full"); m_total_players = total_players; - NetworkingLobby::getInstance()->updatePlayers(players); + NetworkingLobby::getInstance()->updatePlayers(); } // updatePlayerList //----------------------------------------------------------------------------- diff --git a/src/network/protocols/client_lobby.hpp b/src/network/protocols/client_lobby.hpp index caf1ef1f2..8511e9045 100644 --- a/src/network/protocols/client_lobby.hpp +++ b/src/network/protocols/client_lobby.hpp @@ -29,10 +29,24 @@ #include enum PeerDisconnectInfo : unsigned int; +enum KartTeam : int8_t; +enum PerPlayerDifficulty : uint8_t; class BareNetworkString; class Server; +struct LobbyPlayer +{ + irr::core::stringw m_user_name; + int m_local_player_id; + uint32_t m_host_id; + KartTeam m_kart_team; + PerPlayerDifficulty m_difficulty; + uint32_t m_online_id; + /* Icon used in networking lobby, see NetworkingLobby::loadedFromFile. */ + int m_icon_id; +}; + class ClientLobby : public LobbyProtocol { private: @@ -81,6 +95,8 @@ private: bool m_spectator; + bool m_server_live_joinable; + uint64_t m_auto_back_to_lobby_time; uint64_t m_start_live_game_time; @@ -97,6 +113,8 @@ private: std::map m_disconnected_msg; + std::vector m_lobby_players; + irr::core::stringw m_total_players; void liveJoinAcknowledged(Event* event); @@ -131,6 +149,9 @@ public: bool isSpectator() const { return m_spectator; } void startLiveJoinKartSelection(); void sendChat(irr::core::stringw text); + const std::vector& getLobbyPlayers() const + { return m_lobby_players; } + bool isServerLiveJoinable() const { return m_server_live_joinable; } }; #endif // CLIENT_LOBBY_HPP diff --git a/src/states_screens/online/networking_lobby.cpp b/src/states_screens/online/networking_lobby.cpp index 2f9dd453f..c4da6b3c6 100644 --- a/src/states_screens/online/networking_lobby.cpp +++ b/src/states_screens/online/networking_lobby.cpp @@ -166,9 +166,8 @@ void NetworkingLobby::init() m_player_names.clear(); m_allow_change_team = false; m_has_auto_start_in_server = false; - m_server_live_joinable = false; m_client_live_joinable = false; - m_ping_update_timer = 0.0f; + m_ping_update_timer = 0; m_start_timeout = std::numeric_limits::max(); m_cur_starting_timer = std::numeric_limits::max(); m_min_start_game_players = 0; @@ -227,6 +226,11 @@ void NetworkingLobby::init() getWidget("send")->setVisible(true); getWidget("send")->setActive(false); } + if (auto cl = LobbyProtocol::get()) + { + if (cl->isLobbyReady()) + updatePlayers(); + } } } // init @@ -281,10 +285,9 @@ void NetworkingLobby::onUpdate(float delta) m_config_button->setImage(m_config_texture); m_client_live_joinable = false; - m_ping_update_timer += delta; - if (m_player_list && m_ping_update_timer > 2.0f) + if (m_player_list && StkTime::getRealTimeMs() > m_ping_update_timer) { - m_ping_update_timer = 0.0f; + m_ping_update_timer = StkTime::getRealTimeMs() + 2000; updatePlayerPings(); } @@ -355,7 +358,7 @@ void NetworkingLobby::onUpdate(float delta) // and network timer is synchronized if (t && STKHost::get()->getNetworkTimerSynchronizer()->isSynchronised() && - m_server_live_joinable) + cl->isServerLiveJoinable()) { m_client_live_joinable = true; } @@ -490,7 +493,7 @@ void NetworkingLobby::updatePlayerPings() auto peer_pings = STKHost::get()->getPeerPings(); for (auto& p : m_player_names) { - core::stringw name_with_ping = std::get<0>(p.second); + core::stringw name_with_ping = p.second.m_user_name; auto host_online_ids = StringUtils::splitToUInt(p.first, '_'); if (host_online_ids.size() != 3) continue; @@ -506,11 +509,14 @@ void NetworkingLobby::updatePlayerPings() else continue; int id = m_player_list->getItemID(p.first); - m_player_list->renameItem(id, name_with_ping, std::get<1>(p.second)); - if (std::get<2>(p.second) == KART_TEAM_RED) - m_player_list->markItemRed(id); - else if (std::get<2>(p.second) == KART_TEAM_BLUE) - m_player_list->markItemBlue(id); + if (id != -1) + { + m_player_list->renameItem(id, name_with_ping, p.second.m_icon_id); + if (p.second.m_kart_team == KART_TEAM_RED) + m_player_list->markItemRed(id); + else if (p.second.m_kart_team == KART_TEAM_BLUE) + m_player_list->markItemBlue(id); + } } } // updatePlayerPings @@ -541,11 +547,11 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, } new NetworkUserDialog(host_online_local_ids[0], host_online_local_ids[1], host_online_local_ids[2], - std::get<0>(m_player_names.at( - m_player_list->getSelectionInternalName())), + m_player_names.at( + m_player_list->getSelectionInternalName()).m_user_name, m_allow_change_team, - std::get<3>(m_player_names.at( - m_player_list->getSelectionInternalName()))); + m_player_names.at( + m_player_list->getSelectionInternalName()).m_difficulty); } // click on a user else if (name == m_send_button->m_properties[PROP_ID]) { @@ -624,9 +630,7 @@ bool NetworkingLobby::onEscapePressed() } // onEscapePressed // ---------------------------------------------------------------------------- -void NetworkingLobby::updatePlayers(const std::vector >& p) +void NetworkingLobby::updatePlayers() { // In GUI-less server this function will be called without proper // initialisation @@ -635,32 +639,36 @@ void NetworkingLobby::updatePlayers(const std::vectorclear(); m_player_names.clear(); - if (p.empty()) + auto cl = LobbyProtocol::get(); + if (!cl) + return; + + const auto& players = cl->getLobbyPlayers(); + if (players.empty()) return; irr::gui::STKModifiedSpriteBank* icon_bank = m_icon_bank; - for (unsigned i = 0; i < p.size(); i++) + for (unsigned i = 0; i < players.size(); i++) { - auto& q = p[i]; + const LobbyPlayer& player = players[i]; if (icon_bank) { m_player_list->setIcons(icon_bank); icon_bank = NULL; } - KartTeam cur_team = std::get<5>(q); + KartTeam cur_team = player.m_kart_team; m_allow_change_team = cur_team != KART_TEAM_NONE; const std::string internal_name = - StringUtils::toString(std::get<0>(q)) + "_" + - StringUtils::toString(std::get<1>(q)) + "_" + - StringUtils::toString(std::get<2>(q)); - m_player_list->addItem(internal_name, std::get<3>(q), std::get<4>(q)); + StringUtils::toString(player.m_host_id) + "_" + + StringUtils::toString(player.m_online_id) + "_" + + StringUtils::toString(player.m_local_player_id); + m_player_list->addItem(internal_name, player.m_user_name, + player.m_icon_id); if (cur_team == KART_TEAM_RED) m_player_list->markItemRed(i); else if (cur_team == KART_TEAM_BLUE) m_player_list->markItemBlue(i); - m_player_names[internal_name] = - std::make_tuple(std::get<3>(q), std::get<4>(q), cur_team, - std::get<6>(q)); + m_player_names[internal_name] = player; } updatePlayerPings(); } // updatePlayers diff --git a/src/states_screens/online/networking_lobby.hpp b/src/states_screens/online/networking_lobby.hpp index 35dced10c..6212aa4d1 100644 --- a/src/states_screens/online/networking_lobby.hpp +++ b/src/states_screens/online/networking_lobby.hpp @@ -28,6 +28,7 @@ class InputDevice; class Server; enum KartTeam : int8_t; +struct LobbyPlayer; namespace GUIEngine { @@ -65,9 +66,8 @@ private: NetworkingLobby(); - float m_ping_update_timer; - std::map > m_player_names; + uint64_t m_ping_update_timer; + std::map m_player_names; std::shared_ptr m_joined_server; std::vector m_server_info; int m_server_info_height; @@ -80,8 +80,7 @@ private: unsigned m_min_start_game_players; bool m_allow_change_team, m_has_auto_start_in_server, - m_server_configurable, m_server_live_joinable, - m_client_live_joinable; + m_server_configurable, m_client_live_joinable; video::ITexture* m_config_texture; video::ITexture* m_spectate_texture; @@ -135,10 +134,7 @@ public: m_joined_server = server; m_server_info.clear(); } - void updatePlayers(const std::vector >& p); + void updatePlayers(); void openSplitscreenDialog(InputDevice* device); void addSplitscreenPlayer(irr::core::stringw name); void cleanAddedPlayers(); @@ -146,7 +142,6 @@ public: float start_timeout, unsigned server_max_player); void setStartingTimerTo(float t); void toggleServerConfigButton(bool val) { m_server_configurable = val; } - void toggleServerLiveJoinable(bool val) { m_server_live_joinable = val; } }; // class NetworkingLobby #endif