Save players and live join info in ClientLobby

This commit is contained in:
Benau 2019-01-16 16:45:27 +08:00
parent 4e2b843f71
commit 9078438b23
4 changed files with 88 additions and 67 deletions

View File

@ -94,6 +94,7 @@ ClientLobby::ClientLobby(const TransportAddress& a, std::shared_ptr<Server> 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<std::tuple<uint32_t, uint32_t, uint32_t, core::stringw,
int, KartTeam, PerPlayerDifficulty> > players;
core::stringw total_players;
m_lobby_players.clear();
for (unsigned i = 0; i < player_count; i++)
{
std::tuple<uint32_t, uint32_t, uint32_t, core::stringw, int,
KartTeam, PerPlayerDifficulty> 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
//-----------------------------------------------------------------------------

View File

@ -29,10 +29,24 @@
#include <set>
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<PeerDisconnectInfo, irr::core::stringw> m_disconnected_msg;
std::vector<LobbyPlayer> 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<LobbyPlayer>& getLobbyPlayers() const
{ return m_lobby_players; }
bool isServerLiveJoinable() const { return m_server_live_joinable; }
};
#endif // CLIENT_LOBBY_HPP

View File

@ -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<float>::max();
m_cur_starting_timer = std::numeric_limits<int64_t>::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<ClientLobby>())
{
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<std::tuple<uint32_t,
uint32_t, uint32_t, core::stringw,
int, KartTeam, PerPlayerDifficulty> >& 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::vector<std::tuple<uint32_t,
m_player_list->clear();
m_player_names.clear();
if (p.empty())
auto cl = LobbyProtocol::get<ClientLobby>();
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

View File

@ -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<std::string, std::tuple<core::stringw, /*icon*/int, KartTeam,
PerPlayerDifficulty> > m_player_names;
uint64_t m_ping_update_timer;
std::map<std::string, LobbyPlayer> m_player_names;
std::shared_ptr<Server> m_joined_server;
std::vector<core::stringw> 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<std::tuple<uint32_t/*host id*/,
uint32_t/*online id*/, uint32_t/*local player id*/,
core::stringw/*player name*/, int/*icon id*/,
KartTeam, PerPlayerDifficulty> >& 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