Show ping of remote players in lobby
This commit is contained in:
parent
a44ce60991
commit
e1dfe2e7e0
@ -59,10 +59,10 @@
|
||||
#include "main_loop.hpp"
|
||||
#include "modes/profile_world.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
#include "physics/physics.hpp"
|
||||
#include "scriptengine/property_animator.hpp"
|
||||
#include "states_screens/dialogs/confirm_resolution_dialog.hpp"
|
||||
#include "states_screens/networking_lobby.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "tracks/track_manager.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
@ -1729,13 +1729,15 @@ void IrrDriver::displayFPS()
|
||||
prev_state = current_state;
|
||||
}
|
||||
|
||||
uint32_t ping = 0;
|
||||
if (STKHost::existHost())
|
||||
ping = STKHost::get()->getClientPingToServer();
|
||||
if (no_trust)
|
||||
{
|
||||
no_trust--;
|
||||
|
||||
static video::SColor fpsColor = video::SColor(255, 0, 0, 0);
|
||||
font->draw(StringUtils::insertValues (L"FPS: ... Ping: %dms",
|
||||
NetworkingLobby::getInstance()->getServerPing()),
|
||||
font->draw(StringUtils::insertValues (L"FPS: ... Ping: %dms", ping),
|
||||
core::rect< s32 >(100,0,400,50), fpsColor, false);
|
||||
return;
|
||||
}
|
||||
@ -1761,22 +1763,19 @@ void IrrDriver::displayFPS()
|
||||
"Ping: %dms",
|
||||
min, fps, max, SP::sp_solid_poly_count,
|
||||
SP::sp_shadow_poly_count, m_last_light_bucket_distance,
|
||||
m_skinning_joint,
|
||||
NetworkingLobby::getInstance()->getServerPing());
|
||||
m_skinning_joint, ping);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
fps_string = _("FPS: %d/%d/%d - %d KTris, Ping: %dms", min, fps,
|
||||
max, SP::sp_solid_poly_count / 1000,
|
||||
NetworkingLobby::getInstance()->getServerPing());
|
||||
max, SP::sp_solid_poly_count / 1000, ping);
|
||||
}
|
||||
else
|
||||
{
|
||||
fps_string = _("FPS: %d/%d/%d - %d KTris, Ping: %dms", min, fps,
|
||||
max, (int)roundf(kilotris),
|
||||
NetworkingLobby::getInstance()->getServerPing());
|
||||
max, (int)roundf(kilotris), ping);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ private:
|
||||
std::string m_kart_name;
|
||||
|
||||
/** The local player id relative to each peer. */
|
||||
int m_local_player_id;
|
||||
uint8_t m_local_player_id;
|
||||
|
||||
/** Score if grand prix. */
|
||||
int m_score;
|
||||
@ -96,7 +96,7 @@ public:
|
||||
const std::string &getKartName() const { return m_kart_name; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Retuens the local player id for this player. */
|
||||
int getLocalPlayerId() const { return m_local_player_id; }
|
||||
uint8_t getLocalPlayerId() const { return m_local_player_id; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the per-player difficulty. */
|
||||
PerPlayerDifficulty getPerPlayerDifficulty() const
|
||||
|
@ -168,6 +168,10 @@ public:
|
||||
int decodeString(std::string *out) const;
|
||||
int decodeStringW(irr::core::stringw *out) const;
|
||||
std::string getLogMessage(const std::string &indent="") const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the internal buffer of the network string. */
|
||||
std::vector<uint8_t>& getBuffer() { return m_buffer; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a byte pointer to the content of the network string. */
|
||||
char* getData() { return (char*)(m_buffer.data()); };
|
||||
|
@ -548,19 +548,21 @@ void ClientLobby::updatePlayerList(Event* event)
|
||||
if (!checkDataSize(event, 1)) return;
|
||||
NetworkString& data = event->data();
|
||||
unsigned player_count = data.getUInt8();
|
||||
std::vector<std::tuple<uint32_t, uint32_t, core::stringw, int> > players;
|
||||
std::vector<std::tuple<uint32_t, uint32_t, uint32_t, core::stringw,
|
||||
int> > players;
|
||||
for (unsigned i = 0; i < player_count; i++)
|
||||
{
|
||||
std::tuple<uint32_t, uint32_t, core::stringw, int> pl;
|
||||
std::tuple<uint32_t, uint32_t, uint32_t, core::stringw, int> pl;
|
||||
std::get<0>(pl) = data.getUInt32();
|
||||
std::get<1>(pl) = data.getUInt32();
|
||||
data.decodeStringW(&std::get<2>(pl));
|
||||
std::get<2>(pl) = data.getUInt8();
|
||||
data.decodeStringW(&std::get<3>(pl));
|
||||
// icon to be used, see NetworkingLobby::loadedFromFile
|
||||
std::get<3>(pl) = data.getUInt8() == 1 /*if server owner*/ ? 0 :
|
||||
std::get<4>(pl) = data.getUInt8() == 1 /*if server owner*/ ? 0 :
|
||||
std::get<1>(pl) != 0 /*if online account*/ ? 1 : 2;
|
||||
PerPlayerDifficulty d = (PerPlayerDifficulty)data.getUInt8();
|
||||
if (d == PLAYER_DIFFICULTY_HANDICAP)
|
||||
std::get<2>(pl) = _("%s (handicapped)", std::get<2>(pl));
|
||||
std::get<3>(pl) = _("%s (handicapped)", std::get<3>(pl));
|
||||
players.push_back(pl);
|
||||
}
|
||||
NetworkingLobby::getInstance()->updatePlayers(players);
|
||||
|
@ -1406,6 +1406,7 @@ void ServerLobby::updatePlayerList(bool force_update)
|
||||
for (auto profile : all_profiles)
|
||||
{
|
||||
pl->addUInt32(profile->getHostId()).addUInt32(profile->getOnlineId())
|
||||
.addUInt8(profile->getLocalPlayerId())
|
||||
.encodeString(profile->getName());
|
||||
uint8_t server_owner = 0;
|
||||
if (m_server_owner_id.load() == profile->getPeer()->getHostId())
|
||||
|
@ -251,7 +251,7 @@ constexpr std::array<uint8_t, 5> g_ping_packet {{ 255, 'p', 'i', 'n', 'g' }};
|
||||
// ============================================================================
|
||||
constexpr bool isPingPacket(unsigned char* data, size_t length)
|
||||
{
|
||||
return length == g_ping_packet.size() && data[0] == g_ping_packet[0] &&
|
||||
return length > g_ping_packet.size() && data[0] == g_ping_packet[0] &&
|
||||
data[1] == g_ping_packet[1] && data[2] == g_ping_packet[2] &&
|
||||
data[3] == g_ping_packet[3] && data[4] == g_ping_packet[4];
|
||||
} // isPingPacket
|
||||
@ -305,6 +305,7 @@ void STKHost::init()
|
||||
m_authorised = false;
|
||||
m_network = NULL;
|
||||
m_exit_timeout.store(std::numeric_limits<double>::max());
|
||||
m_client_ping.store(0);
|
||||
|
||||
// Start with initialising ENet
|
||||
// ============================
|
||||
@ -713,19 +714,9 @@ void STKHost::mainLoop()
|
||||
}
|
||||
|
||||
double last_ping_time = StkTime::getRealTime();
|
||||
double last_ping_time_update_for_client = StkTime::getRealTime();
|
||||
while (m_exit_timeout.load() > StkTime::getRealTime())
|
||||
{
|
||||
if (!is_server)
|
||||
{
|
||||
auto server_peer = getServerPeerForClient();
|
||||
if (server_peer &&
|
||||
StkTime::getRealTime() - server_peer->getConnectedTime() > 3.0)
|
||||
{
|
||||
// Back to default ping interval for client
|
||||
server_peer->setPingInterval(0);
|
||||
}
|
||||
}
|
||||
|
||||
auto sl = LobbyProtocol::get<ServerLobby>();
|
||||
if (direct_socket && sl && sl->waitingForPlayers())
|
||||
{
|
||||
@ -746,12 +737,29 @@ void STKHost::mainLoop()
|
||||
1.0 / double(stk_config->m_network_state_frequeny);
|
||||
need_ping = true;
|
||||
}
|
||||
|
||||
if (need_ping)
|
||||
{
|
||||
m_peer_pings.getData().clear();
|
||||
for (auto& p : m_peers)
|
||||
{
|
||||
m_peer_pings.getData()[p.second->getHostId()] =
|
||||
p.second->getPing();
|
||||
}
|
||||
}
|
||||
for (auto it = m_peers.begin(); it != m_peers.end();)
|
||||
{
|
||||
if (need_ping)
|
||||
{
|
||||
ENetPacket* packet = enet_packet_create(g_ping_packet.data(),
|
||||
g_ping_packet.size(), ENET_PACKET_FLAG_RELIABLE);
|
||||
BareNetworkString ping_packet;
|
||||
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);
|
||||
ping_packet.getBuffer().insert(
|
||||
ping_packet.getBuffer().begin(), g_ping_packet.begin(),
|
||||
g_ping_packet.end());
|
||||
ENetPacket* packet = enet_packet_create(ping_packet.getData(),
|
||||
ping_packet.getTotalSize(), ENET_PACKET_FLAG_RELIABLE);
|
||||
enet_peer_send(it->first, EVENT_CHANNEL_UNENCRYPTED, packet);
|
||||
}
|
||||
|
||||
@ -804,8 +812,28 @@ void STKHost::mainLoop()
|
||||
}
|
||||
}
|
||||
|
||||
bool need_ping_update = false;
|
||||
while (enet_host_service(host, &event, 10) != 0)
|
||||
{
|
||||
if (!is_server &&
|
||||
last_ping_time_update_for_client < StkTime::getRealTime())
|
||||
{
|
||||
last_ping_time_update_for_client =
|
||||
StkTime::getRealTime() + 2.0;
|
||||
auto lp = LobbyProtocol::get<LobbyProtocol>();
|
||||
if (lp && lp->isRacing())
|
||||
{
|
||||
auto p = getServerPeerForClient();
|
||||
if (p)
|
||||
{
|
||||
m_client_ping.store(p->getPing(),
|
||||
std::memory_order_relaxed);
|
||||
}
|
||||
need_ping_update = false;
|
||||
}
|
||||
else
|
||||
need_ping_update = true;
|
||||
}
|
||||
if (event.type == ENET_EVENT_TYPE_NONE)
|
||||
continue;
|
||||
|
||||
@ -854,6 +882,24 @@ void STKHost::mainLoop()
|
||||
auto& peer = m_peers.at(event.peer);
|
||||
if (isPingPacket(event.packet->data, event.packet->dataLength))
|
||||
{
|
||||
if (!is_server && need_ping_update)
|
||||
{
|
||||
m_peer_pings.lock();
|
||||
m_peer_pings.getData().clear();
|
||||
BareNetworkString ping_packet((char*)event.packet->data,
|
||||
event.packet->dataLength);
|
||||
ping_packet.skip(g_ping_packet.size());
|
||||
unsigned peer_size = ping_packet.getUInt8();
|
||||
for (unsigned i = 0; i < peer_size; i++)
|
||||
{
|
||||
unsigned host_id = ping_packet.getUInt32();
|
||||
unsigned ping = ping_packet.getUInt32();
|
||||
m_peer_pings.getData()[host_id] = ping;
|
||||
}
|
||||
m_client_ping.store(m_peer_pings.getData()[m_host_id],
|
||||
std::memory_order_relaxed);
|
||||
m_peer_pings.unlock();
|
||||
}
|
||||
enet_packet_destroy(event.packet);
|
||||
continue;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "network/network.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/transport_address.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
|
||||
#include "irrString.h"
|
||||
|
||||
@ -132,6 +133,10 @@ private:
|
||||
/** The private port enet socket is bound. */
|
||||
uint16_t m_private_port;
|
||||
|
||||
Synchronised<std::map<uint32_t, uint32_t> > m_peer_pings;
|
||||
|
||||
std::atomic<uint32_t> m_client_ping;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
STKHost(bool server);
|
||||
// ------------------------------------------------------------------------
|
||||
@ -301,7 +306,12 @@ public:
|
||||
bool isClientServer() const { return m_separate_process != NULL; }
|
||||
// ------------------------------------------------------------------------
|
||||
void replaceNetwork(ENetEvent& event, Network* network);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
std::map<uint32_t, uint32_t> getPeerPings()
|
||||
{ return m_peer_pings.getAtomic(); }
|
||||
// ------------------------------------------------------------------------
|
||||
uint32_t getClientPingToServer() const
|
||||
{ return m_client_ping.load(std::memory_order_relaxed); }
|
||||
}; // class STKHost
|
||||
|
||||
#endif // STK_HOST_HPP
|
||||
|
@ -20,9 +20,7 @@
|
||||
#include "config/user_config.hpp"
|
||||
#include "network/crypto.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/network_player_profile.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
#include "network/transport_address.hpp"
|
||||
#include "utils/log.hpp"
|
||||
@ -39,12 +37,6 @@ STKPeer::STKPeer(ENetPeer *enet_peer, STKHost* host, uint32_t host_id)
|
||||
m_host_id = host_id;
|
||||
m_connected_time = (float)StkTime::getRealTime();
|
||||
m_validated.store(false);
|
||||
if (NetworkConfig::get()->isClient())
|
||||
{
|
||||
// This allow client to get the correct ping as fast as possible
|
||||
// reset to default (0) will be done in STKHost::mainloop after 3 sec
|
||||
setPingInterval(10);
|
||||
}
|
||||
} // STKPeer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "states_screens/networking_lobby.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
@ -38,7 +39,6 @@
|
||||
#include "network/protocols/lobby_protocol.hpp"
|
||||
#include "network/server.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
#include "network/stk_peer.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "states_screens/dialogs/network_user_dialog.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
@ -135,6 +135,7 @@ void NetworkingLobby::init()
|
||||
{
|
||||
Screen::init();
|
||||
|
||||
m_ping_update_timer = 0.0f;
|
||||
m_cur_starting_timer = m_start_threshold = m_start_timeout =
|
||||
m_server_max_player = std::numeric_limits<float>::max();
|
||||
m_timeout_message->setVisible(false);
|
||||
@ -269,8 +270,6 @@ void NetworkingLobby::onUpdate(float delta)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_server_peer.expired() && STKHost::existHost())
|
||||
m_server_peer = STKHost::get()->getServerPeerForClient();
|
||||
core::stringw total_msg;
|
||||
for (auto& string : m_server_info)
|
||||
{
|
||||
@ -280,26 +279,47 @@ void NetworkingLobby::onUpdate(float delta)
|
||||
m_text_bubble->setText(total_msg, true);
|
||||
}
|
||||
|
||||
m_ping_update_timer += delta;
|
||||
if (m_player_list && m_ping_update_timer > 2.0f)
|
||||
{
|
||||
m_ping_update_timer = 0.0f;
|
||||
updatePlayerPings();
|
||||
}
|
||||
if (STKHost::get()->isAuthorisedToControl())
|
||||
{
|
||||
m_start_button->setVisible(true);
|
||||
}
|
||||
//I18N: In the networking lobby, display ping when connected
|
||||
const uint32_t ping = getServerPing();
|
||||
const uint32_t ping = STKHost::get()->getClientPingToServer();
|
||||
if (ping != 0)
|
||||
m_header->setText(_("Lobby (ping: %dms)", ping), false);
|
||||
|
||||
} // onUpdate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
uint32_t NetworkingLobby::getServerPing() const
|
||||
void NetworkingLobby::updatePlayerPings()
|
||||
{
|
||||
if (auto p = m_server_peer.lock())
|
||||
auto peer_pings = STKHost::get()->getPeerPings();
|
||||
for (auto& p : m_player_names)
|
||||
{
|
||||
return p->getPing();
|
||||
core::stringw name_with_ping = p.second.first;
|
||||
auto host_online_ids = StringUtils::splitToUInt(p.first, '_');
|
||||
if (host_online_ids.size() != 3)
|
||||
continue;
|
||||
unsigned ping = 0;
|
||||
uint32_t host_id = host_online_ids[0];
|
||||
if (peer_pings.find(host_id) != peer_pings.end())
|
||||
ping = peer_pings.at(host_id);
|
||||
if (ping != 0)
|
||||
{
|
||||
name_with_ping = StringUtils::insertValues(L"%s (%dms)",
|
||||
name_with_ping, ping);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
m_player_list->renameItem(p.first, name_with_ping, p.second.second);
|
||||
}
|
||||
return 0;
|
||||
} // getServerPing
|
||||
} // updatePlayerPings
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void NetworkingLobby::sendChat(irr::core::stringw text)
|
||||
@ -336,12 +356,13 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name,
|
||||
{
|
||||
auto host_online_ids = StringUtils::splitToUInt
|
||||
(m_player_list->getSelectionInternalName(), '_');
|
||||
if (host_online_ids.size() != 2)
|
||||
if (host_online_ids.size() != 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
new NetworkUserDialog(host_online_ids[0], host_online_ids[1],
|
||||
m_player_list->getSelectionLabel());
|
||||
m_player_names.at(
|
||||
m_player_list->getSelectionInternalName()).first);
|
||||
} // click on a user
|
||||
else if (name == m_send_button->m_properties[PROP_ID])
|
||||
{
|
||||
@ -389,13 +410,15 @@ bool NetworkingLobby::onEscapePressed()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void NetworkingLobby::updatePlayers(const std::vector<std::tuple<uint32_t,
|
||||
uint32_t, core::stringw, int> >& p)
|
||||
uint32_t, uint32_t, core::stringw,
|
||||
int> >& p)
|
||||
{
|
||||
// In GUI-less server this function will be called without proper
|
||||
// initialisation
|
||||
if (!m_player_list)
|
||||
return;
|
||||
m_player_list->clear();
|
||||
m_player_names.clear();
|
||||
|
||||
if (p.empty())
|
||||
return;
|
||||
@ -410,9 +433,12 @@ void NetworkingLobby::updatePlayers(const std::vector<std::tuple<uint32_t,
|
||||
}
|
||||
const std::string internal_name =
|
||||
StringUtils::toString(std::get<0>(q)) + "_" +
|
||||
StringUtils::toString(std::get<1>(q));
|
||||
m_player_list->addItem(internal_name, std::get<2>(q), std::get<3>(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));
|
||||
m_player_names[internal_name] = { std::get<3>(q), std::get<4>(q) };
|
||||
}
|
||||
updatePlayerPings();
|
||||
} // updatePlayers
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -447,6 +473,7 @@ void NetworkingLobby::cleanAddedPlayers()
|
||||
if (!m_player_list)
|
||||
return;
|
||||
m_player_list->clear();
|
||||
m_player_names.clear();
|
||||
} // cleanAddedPlayers
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -20,11 +20,12 @@
|
||||
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widgets/text_box_widget.hpp"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
class Server;
|
||||
class STKPeer;
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
@ -62,8 +63,10 @@ private:
|
||||
|
||||
NetworkingLobby();
|
||||
|
||||
float m_ping_update_timer;
|
||||
std::map<std::string, std::pair<core::stringw, /*icon*/int> >
|
||||
m_player_names;
|
||||
std::shared_ptr<Server> m_joined_server;
|
||||
std::weak_ptr<STKPeer> m_server_peer;
|
||||
std::vector<core::stringw> m_server_info;
|
||||
int m_server_info_height;
|
||||
|
||||
@ -93,6 +96,7 @@ private:
|
||||
}
|
||||
|
||||
void sendChat(irr::core::stringw text);
|
||||
void updatePlayerPings();
|
||||
|
||||
public:
|
||||
|
||||
@ -125,11 +129,10 @@ public:
|
||||
m_server_info.clear();
|
||||
}
|
||||
void updatePlayers(const std::vector<std::tuple<uint32_t/*host id*/,
|
||||
uint32_t/*online id*/, core::stringw/*player name*/,
|
||||
int/*icon id*/> >& p);
|
||||
uint32_t/*online id*/, uint32_t/*local player id*/,
|
||||
core::stringw/*player name*/, int/*icon id*/> >& p);
|
||||
void addSplitscreenPlayer(irr::core::stringw name);
|
||||
void cleanAddedPlayers();
|
||||
uint32_t getServerPing() const;
|
||||
void initAutoStartTimer(bool grand_prix_started, float start_threshold,
|
||||
float start_timeout, unsigned server_max_player);
|
||||
void setStartingTimerTo(float t) { m_cur_starting_timer = t; }
|
||||
|
Loading…
Reference in New Issue
Block a user