From 3ee3d8d5bd5b221d2009a5f5954179d33ea8afb9 Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 23 Mar 2018 18:51:26 +0800 Subject: [PATCH] Randomly use stun servers of the low ping from top-half of the list --- src/config/user_config.cpp | 143 +------------------------ src/config/user_config.hpp | 117 ++++++++------------ src/network/network_console.cpp | 4 +- src/network/protocols/server_lobby.cpp | 8 +- src/network/stk_host.cpp | 33 ++++-- 5 files changed, 75 insertions(+), 230 deletions(-) diff --git a/src/config/user_config.cpp b/src/config/user_config.cpp index 0bff3878a..5c53ee2d9 100644 --- a/src/config/user_config.cpp +++ b/src/config/user_config.cpp @@ -181,146 +181,6 @@ void GroupUserConfigParam::addChild(UserConfigParam* child) m_attributes.push_back(child); } // addChild - -// ============================================================================ -template -ListUserConfigParam::ListUserConfigParam(const char* param_name, - const char* comment) -{ - m_param_name = param_name; - all_params.push_back(this); - if(comment != NULL) m_comment = comment; -} // ListUserConfigParam - -// ============================================================================ -template -ListUserConfigParam::ListUserConfigParam(const char* param_name, - const char* comment, - int nb_elements, - ...) -{ - m_param_name = param_name; - all_params.push_back(this); - if(comment != NULL) m_comment = comment; - - // add the default list - va_list arguments; - va_start ( arguments, nb_elements ); - for ( int i = 0; i < nb_elements; i++ ) - m_elements.push_back(T(va_arg ( arguments, U ))); - va_end ( arguments ); // Cleans up the list -} // ListUserConfigParam - -// ============================================================================ -template -ListUserConfigParam::ListUserConfigParam(const char* param_name, - GroupUserConfigParam* group, - const char* comment) -{ - m_param_name = param_name; - group->addChild(this); - if(comment != NULL) m_comment = comment; -} // ListUserConfigParam - -// ============================================================================ -template -ListUserConfigParam::ListUserConfigParam(const char* param_name, - GroupUserConfigParam* group, - const char* comment, - int nb_elements, - ...) -{ - m_param_name = param_name; - group->addChild(this); - if(comment != NULL) m_comment = comment; - - // add the default list - va_list arguments; - va_start ( arguments, nb_elements ); - for ( int i = 0; i < nb_elements; i++ ) - m_elements.push_back(va_arg ( arguments, T )); - va_end ( arguments ); // Cleans up the list -} // ListUserConfigParam - -// ---------------------------------------------------------------------------- -template -void ListUserConfigParam::write(std::ofstream& stream) const -{ - const int elts_amount = (int)m_elements.size(); - - // comment - if(m_comment.size() > 0) stream << " \n <" << m_param_name.c_str() << "\n"; - - stream << " Size=\"" << elts_amount << "\"\n"; - // actual elements - for (int n=0; n\n"; - stream << " \n\n"; -} // write - -// ---------------------------------------------------------------------------- - -template -void ListUserConfigParam::findYourDataInAChildOf(const XMLNode* node) -{ - const XMLNode* child = node->getNode( m_param_name ); - if (child == NULL) - { - //Log::error("User Config", "Couldn't find parameter group %s", m_param_name.c_str()); - return; - } - - int attr_count = 0; - child->get( "Size", &attr_count); - for (int n=0; nget( StringUtils::toString(n), &str); - StringUtils::fromString(str, elt); - - // check if the element is already there : - bool there = false; - for (unsigned int i = 0; i < m_elements.size(); i++) - { - if (elt == m_elements[i]) - { - there = true; - break; - } - } - if (!there) - { - m_elements.push_back(elt); - } - } - -} // findYourDataInAChildOf - -// ---------------------------------------------------------------------------- -template -void ListUserConfigParam::findYourDataInAnAttributeOf(const XMLNode* node) -{ -} // findYourDataInAnAttributeOf - -// ---------------------------------------------------------------------------- -template -void ListUserConfigParam::addElement(T element) -{ - m_elements.push_back(element); -} // findYourDataInAnAttributeOf - -// ---------------------------------------------------------------------------- -template -core::stringc ListUserConfigParam::toString() const -{ - return ""; -} // toString - // ---------------------------------------------------------------------------- template MapUserConfigParam::MapUserConfigParam(const char* param_name, @@ -374,7 +234,7 @@ void MapUserConfigParam::write(std::ofstream& stream) const if (m_comment.size() > 0) stream << " \n <" << m_param_name.c_str() << "\n"; - for (const auto& kv : m_elements) + for (const auto& kv : m_elements) { stream << " " << kv.first << "=\"" << kv.second << "\"\n"; } @@ -383,7 +243,6 @@ void MapUserConfigParam::write(std::ofstream& stream) const } // write // ---------------------------------------------------------------------------- - template void MapUserConfigParam::findYourDataInAChildOf(const XMLNode* node) { diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index c6e9838e7..22d65a878 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -37,6 +37,7 @@ cause an undefined game action now 6: Added stick configurations. */ +#include #include #include #include @@ -98,44 +99,6 @@ public: }; // GroupUserConfigParam // ============================================================================ -template -class ListUserConfigParam : public UserConfigParam -{ - std::vector m_elements; - -public: - ListUserConfigParam(const char* param_name, - const char* comment = NULL); - ListUserConfigParam(const char* param_name, - const char* comment, - int nb_elts, - ...); - ListUserConfigParam(const char* param_name, - GroupUserConfigParam* group, - const char* comment = NULL); - ListUserConfigParam(const char* param_name, - GroupUserConfigParam* group, - const char* comment, - int nb_elts, - ...); - - void write(std::ofstream& stream) const; - void findYourDataInAChildOf(const XMLNode* node); - void findYourDataInAnAttributeOf(const XMLNode* node); - - void addElement(T element); - - irr::core::stringc toString() const; - - operator std::vector() const - { return m_elements; } - float& operator=(const std::vector& v) - { m_elements = std::vector(v); return m_elements; } - float& operator=(const ListUserConfigParam& v) - { m_elements = std::vector(v); return m_elements; } -}; // ListUserConfigParam -typedef ListUserConfigParam StringListUserConfigParam; - template class MapUserConfigParam : public UserConfigParam { @@ -163,10 +126,18 @@ public: irr::core::stringc toString() const; - operator std::map() const + operator std::map() const { return m_elements; } + typename std::map::iterator begin() + { + return m_elements.begin(); + } + typename std::map::iterator end() + { + return m_elements.end(); + } std::map& operator=(const std::map& v) { m_elements = std::map(v); @@ -181,7 +152,7 @@ public: { return m_elements[key]; } -}; // ListUserConfigParam +}; // MapUserConfigParam typedef MapUserConfigParam UIntToUIntUserConfigParam; typedef MapUserConfigParam StringToUIntUserConfigParam; // ============================================================================ @@ -707,44 +678,25 @@ namespace UserConfigParams * can store. */ PARAM_PREFIX float m_profiler_buffer_duration PARAM_DEFAULT(20.0f); - // not saved to file - // ---- Networking - - PARAM_PREFIX IntUserConfigParam m_server_max_players - PARAM_DEFAULT( IntUserConfigParam(12, "server_max_players", - "Maximum number of players on the server.") ); - - PARAM_PREFIX StringListUserConfigParam m_stun_servers_list - PARAM_DEFAULT( StringListUserConfigParam("Stun_servers_list", - "The stun servers that will be used to know the public address.", - 10, - "stun.cope.es", - "stun.12connect.com", - "stun.callwithus.com", - "stun.counterpath.net", - "stun.ekiga.net", - "stun.schlund.de", - "stun.stunprotocol.org", - "stun.voip.aebc.com", - "numb.viagenie.ca", - "stun.ivao.aero") ); - - // ---- Gamemode setup - PARAM_PREFIX UIntToUIntUserConfigParam m_num_karts_per_gamemode - PARAM_DEFAULT(UIntToUIntUserConfigParam("num_karts_per_gamemode", - "The Number of karts per gamemode.", + PARAM_PREFIX StringToUIntUserConfigParam m_stun_list + PARAM_DEFAULT(StringToUIntUserConfigParam("stun_list", + "The stun servers that will be used to know the public address," + " LHS: server address, RHS: ping time.", { - { 0u, 4u }, - { 1002u, 5u }, - { 1100u, 4u }, - { 1101u, 4u }, - { 2000u, 4u }, - { 2001u, 4u }, + { "numb.viagenie.ca", 0u }, + { "stun.12connect.com", 0u }, + { "stun.callwithus.com", 0u }, + { "stun.cope.es", 0u }, + { "stun.counterpath.net", 0u }, + { "stun.ekiga.net", 0u }, + { "stun.ivao.aero", 0u }, + { "stun.schlund.de", 0u }, + { "stun.stunprotocol.org", 0u }, + { "stun.voip.aebc.com", 0u } } )); - // ---- Network PARAM_PREFIX GroupUserConfigParam m_network_group PARAM_DEFAULT(GroupUserConfigParam("Network", "Network Settings")); PARAM_PREFIX BoolUserConfigParam m_log_packets @@ -760,7 +712,10 @@ namespace UserConfigParams PARAM_PREFIX FloatUserConfigParam m_voting_timeout PARAM_DEFAULT(FloatUserConfigParam(10.0f, "voting-timeout", &m_network_group, "Timeout in seconds for voting tracks in server.")); - // ---- Gamemode setup + PARAM_PREFIX IntUserConfigParam m_server_max_players + PARAM_DEFAULT(IntUserConfigParam(12, "server_max_players", + &m_network_group, "Maximum number of players on the server.")); + PARAM_PREFIX StringToUIntUserConfigParam m_server_ban_list PARAM_DEFAULT(StringToUIntUserConfigParam("server_ban_list", "LHS: IP in x.x.x.x format, RHS: online id, if 0 than all players " @@ -768,6 +723,20 @@ namespace UserConfigParams { { "0.0.0.0", 0u } } )); + // ---- Gamemode setup + PARAM_PREFIX UIntToUIntUserConfigParam m_num_karts_per_gamemode + PARAM_DEFAULT(UIntToUIntUserConfigParam("num_karts_per_gamemode", + "The Number of karts per gamemode.", + { + { 0u, 4u }, + { 1002u, 5u }, + { 1100u, 4u }, + { 1101u, 4u }, + { 2000u, 4u }, + { 2001u, 4u } + } + )); + // ---- Graphic Quality PARAM_PREFIX GroupUserConfigParam m_graphics_quality PARAM_DEFAULT( GroupUserConfigParam("GFX", diff --git a/src/network/network_console.cpp b/src/network/network_console.cpp index 2076ece25..4612d1823 100644 --- a/src/network/network_console.cpp +++ b/src/network/network_console.cpp @@ -107,9 +107,7 @@ void mainLoop(STKHost* host) } else if (str == "listban") { - std::map ban_list = - UserConfigParams::m_server_ban_list; - for (auto& ban : ban_list) + for (auto& ban : UserConfigParams::m_server_ban_list) { if (ban.first == "0.0.0.0") continue; diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 896a19bf0..549d1964d 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -1242,8 +1242,10 @@ void ServerLobby::updateBanList() { std::lock_guard lock(m_connection_mutex); m_ban_list.clear(); - std::map ban_list = - UserConfigParams::m_server_ban_list; - for (auto& ban : ban_list) + for (auto& ban : UserConfigParams::m_server_ban_list) + { + if (ban.first == "0.0.0.0") + continue; m_ban_list[TransportAddress(ban.first).getIP()] = ban.second; + } } // updateBanList diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index 06aa80849..74980a603 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -385,17 +385,29 @@ void STKHost::shutdown() */ void STKHost::setPublicAddress() { - std::vector untried_server = - UserConfigParams::m_stun_servers_list; - // Generate random list of stun servers + std::vector > untried_server; + for (auto& p : UserConfigParams::m_stun_list) + untried_server.push_back(p); + + assert(untried_server.size() > 2); + // Randomly use stun servers of the low ping from top-half of the list + std::sort(untried_server.begin(), untried_server.end(), + [] (const std::pair& a, + const std::pair& b)->bool + { + return a.second > b.second; + }); std::random_device rd; std::mt19937 g(rd()); - std::shuffle(untried_server.begin(), untried_server.end(), g); + std::shuffle(untried_server.begin() + (untried_server.size() / 2), + untried_server.end(), g); + while (!untried_server.empty()) { // Pick last element in untried servers - const char* server_name = untried_server.back().c_str(); - Log::debug("STKHost", "Using STUN server %s", server_name); + std::string server_name = untried_server.back().first.c_str(); + UserConfigParams::m_stun_list[server_name] = (uint32_t)-1; + Log::debug("STKHost", "Using STUN server %s", server_name.c_str()); struct addrinfo hints, *res; @@ -404,11 +416,11 @@ void STKHost::setPublicAddress() hints.ai_socktype = SOCK_STREAM; // Resolve the stun server name so we can send it a STUN request - int status = getaddrinfo(server_name, NULL, &hints, &res); + int status = getaddrinfo(server_name.c_str(), NULL, &hints, &res); if (status != 0) { Log::error("STKHost", "Error in getaddrinfo for stun server" - " %s: %s", server_name, gai_strerror(status)); + " %s: %s", server_name.c_str(), gai_strerror(status)); untried_server.pop_back(); continue; } @@ -439,6 +451,7 @@ void STKHost::setPublicAddress() } m_network->sendRawPacket(s, m_stun_address); + double ping = StkTime::getRealTime(); freeaddrinfo(res); // Recieve now @@ -446,6 +459,7 @@ void STKHost::setPublicAddress() const int LEN = 2048; char buffer[LEN]; int len = m_network->receiveRawPacket(buffer, LEN, &sender, 2000); + ping = StkTime::getRealTime() - ping; if (sender.getIP() != m_stun_address.getIP()) { @@ -583,6 +597,9 @@ void STKHost::setPublicAddress() Log::warn("STKHost", "Only non xor-mapped address returned."); m_public_address.copy(non_xor_addr); } + // Succeed, save ping + UserConfigParams::m_stun_list[server_name] = + (uint32_t)(ping * 1000.0); untried_server.clear(); } }