Allow to keep the server connection for clients when polling

This commit is contained in:
Benau 2018-09-03 00:48:00 +08:00
parent 0878e59794
commit e2eed9de88
5 changed files with 75 additions and 10 deletions

View File

@ -34,6 +34,7 @@
#include "network/network_config.hpp"
#include "network/network_player_profile.hpp"
#include "network/network_timer_synchronizer.hpp"
#include "network/protocols/connect_to_server.hpp"
#include "network/protocols/game_protocol.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "network/race_event_manager.hpp"
@ -96,6 +97,15 @@ ClientLobby::ClientLobby(const TransportAddress& a, std::shared_ptr<Server> s)
ClientLobby::~ClientLobby()
{
clearPlayers();
if (m_server->supportsEncryption())
{
Online::XMLRequest* request =
new Online::XMLRequest(true/*manager_memory*/);
NetworkConfig::get()->setServerDetails(request,
"clear-user-joined-server");
request->queue();
ConnectToServer::m_previous_unjoin = request->observeExistence();
}
} // ClientLobby
//-----------------------------------------------------------------------------

View File

@ -35,7 +35,8 @@
#include "utils/log.hpp"
#include <algorithm>
// ============================================================================
std::weak_ptr<bool> ConnectToServer::m_previous_unjoin;
// ----------------------------------------------------------------------------
/** Specify server to connect to.
* \param server Server to connect to (if nullptr than we use quick play).
@ -56,6 +57,16 @@ ConnectToServer::ConnectToServer(std::shared_ptr<Server> server)
*/
ConnectToServer::~ConnectToServer()
{
auto cl = LobbyProtocol::get<ClientLobby>();
if (!cl && m_server->supportsEncryption())
{
Online::XMLRequest* request =
new Online::XMLRequest(true/*manager_memory*/);
NetworkConfig::get()->setServerDetails(request,
"clear-user-joined-server");
request->queue();
m_previous_unjoin = request->observeExistence();
}
} // ~ConnectToServer
// ----------------------------------------------------------------------------
@ -82,9 +93,17 @@ void ConnectToServer::asynchronousUpdate()
if (!m_server)
{
while (!ServersManager::get()->refresh(false))
{
if (ProtocolManager::lock()->isExiting())
return;
StkTime::sleep(1);
}
while (!ServersManager::get()->listUpdated())
{
if (ProtocolManager::lock()->isExiting())
return;
StkTime::sleep(1);
}
auto servers = std::move(ServersManager::get()->getServers());
// Remove password protected servers
@ -342,7 +361,14 @@ bool ConnectToServer::handleDirectConnect(int timeout)
void ConnectToServer::registerWithSTKServer()
{
// Our public address is now known, register details with
// STK server.
// STK server. If previous unjoin request is not finished, wait
if (!m_previous_unjoin.expired())
{
if (ProtocolManager::lock()->isExiting())
return;
StkTime::sleep(1);
}
const TransportAddress& addr = STKHost::get()->getPublicAddress();
Online::XMLRequest *request = new Online::XMLRequest();
NetworkConfig::get()->setServerDetails(request, "join-server-key");

View File

@ -55,6 +55,7 @@ private:
void registerWithSTKServer();
void waitingAloha(bool is_wan);
public:
static std::weak_ptr<bool> m_previous_unjoin;
ConnectToServer(std::shared_ptr<Server> server);
virtual ~ConnectToServer();

View File

@ -916,8 +916,12 @@ void ServerLobby::checkIncomingConnectionRequests()
auto sl = m_server_lobby.lock();
if (!sl || (sl->m_state.load() != WAITING_FOR_START_GAME &&
!sl->allowJoinedPlayersWaiting()))
{
sl->replaceKeys(keys);
return;
}
sl->removeExpiredPeerConnection();
for (unsigned int i = 0; i < users_xml->getNumNodes(); i++)
{
uint32_t addr, id;
@ -931,13 +935,18 @@ void ServerLobby::checkIncomingConnectionRequests()
keys[id].m_tried = false;
if (UserConfigParams::m_firewalled_server)
{
std::make_shared<ConnectToPeer>
(TransportAddress(addr, port))->requestStart();
TransportAddress peer_addr(addr, port);
std::string peer_addr_str = peer_addr.toString();
if (sl->m_pending_peer_connection.find(peer_addr_str) !=
sl->m_pending_peer_connection.end())
{
continue;
}
std::make_shared<ConnectToPeer>(peer_addr)->requestStart();
sl->addPeerConnection(peer_addr_str);
}
}
if (keys.empty())
return;
sl->addAndReplaceKeys(keys);
sl->replaceKeys(keys);
}
public:
PollServerRequest(std::shared_ptr<ServerLobby> sl)

View File

@ -22,6 +22,7 @@
#include "network/protocols/lobby_protocol.hpp"
#include "network/transport_address.hpp"
#include "utils/cpp2011.hpp"
#include "utils/time.hpp"
#include "irrString.h"
@ -114,6 +115,8 @@ private:
std::pair<uint32_t, BareNetworkString>,
std::owner_less<std::weak_ptr<STKPeer> > > m_pending_connection;
std::map<std::string, uint64_t> m_pending_peer_connection;
/* Ranking related variables */
// If updating the base points, update the base points distribution in DB
const double BASE_RANKING_POINTS = 4000.0;
@ -187,11 +190,27 @@ private:
}
}
}
void addAndReplaceKeys(const std::map<uint32_t, KeyData>& new_keys)
void addPeerConnection(const std::string& addr_str)
{
m_pending_peer_connection[addr_str] = StkTime::getRealTimeMs();
}
void removeExpiredPeerConnection()
{
// Remove connect to peer protocol running more than a 45 seconds
// (from stk addons poll server request),
for (auto it = m_pending_peer_connection.begin();
it != m_pending_peer_connection.end();)
{
if (StkTime::getRealTimeMs() - it->second > 45000)
it = m_pending_peer_connection.erase(it);
else
it++;
}
}
void replaceKeys(std::map<uint32_t, KeyData>& new_keys)
{
std::lock_guard<std::mutex> lock(m_keys_mutex);
for (auto& k : new_keys)
m_keys[k.first] = k.second;
std::swap(m_keys, new_keys);
}
void handlePendingConnection();
void handleUnencryptedConnection(std::shared_ptr<STKPeer> peer,