Merge branch 'master' of github.com:supertuxkart/stk-code

This commit is contained in:
hiker 2019-01-21 22:40:48 +11:00
commit 040725ae87
15 changed files with 3429 additions and 150 deletions

View File

@ -4,7 +4,7 @@
First of all, you can compile STK with `-DSERVER_ONLY=ON` which will produce a GUI-less STK binary optimized for size and memory usage, useful for situation like in VPS. First of all, you can compile STK with `-DSERVER_ONLY=ON` which will produce a GUI-less STK binary optimized for size and memory usage, useful for situation like in VPS.
### Hosting WAN (public internet) server ### Hosting WAN (public internet) server
You are required to have an stk online account first, go [here](https://addons.supertuxkart.net/register.php) for registration. You are required to have an stk online account first, go [here](https://online.supertuxkart.net/register.php) for registration.
It is recommended you have a saved user in your computer to allow hosting multiple servers simultaneously with the same account, if you have a fresh STK installation, first run: It is recommended you have a saved user in your computer to allow hosting multiple servers simultaneously with the same account, if you have a fresh STK installation, first run:
@ -178,7 +178,7 @@ There is a network AI tester in STK which can use AI on player controller for se
x.x.x.x:y is your server ip address with its port, id is the id field of server-info in STK server xml list, omit it if you are testing LAN server, n is the number of AI you want to create. x.x.x.x:y is your server ip address with its port, id is the id field of server-info in STK server xml list, omit it if you are testing LAN server, n is the number of AI you want to create.
You can see STK server xml list [here](https://addons.supertuxkart.net/api/v2/server/get-all). You can see STK server xml list [here](https://online.supertuxkart.net/api/v2/server/get-all).
You can remove `--auto-connect` if you have another client which can control the starting of games in server, or you can consider enable owner-less mode on server so the games on server can keep going. Remove `--no-graphics` if you want to see the AI racing. You can also run network AI tester in server-only build of STK. You can remove `--auto-connect` if you have another client which can control the starting of games in server, or you can consider enable owner-less mode on server so the games on server can keep going. Remove `--no-graphics` if you want to see the AI racing. You can also run network AI tester in server-only build of STK.

View File

@ -1,21 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDezCCAmOgAwIBAgIJAO+A8uXtEMRsMA0GCSqGSIb3DQEBCwUAMFQxCzAJBgNV
BAYTAlVTMQwwCgYDVQQIDANTVEsxFTATBgNVBAoMDFN1cGVyVHV4S2FydDEgMB4G
A1UEAwwXYWRkb25zLnN1cGVydHV4a2FydC5uZXQwHhcNMTQxMjEwMTEzMTAwWhcN
MjQxMjA3MTEzMTAwWjBUMQswCQYDVQQGEwJVUzEMMAoGA1UECAwDU1RLMRUwEwYD
VQQKDAxTdXBlclR1eEthcnQxIDAeBgNVBAMMF2FkZG9ucy5zdXBlcnR1eGthcnQu
bmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2ysZE9rb4y0tHOhk
wxYpqsvDv5LCRFTAeyfAfyBVDcOn+4A3sX8MkQdoH/QDi823z4bn9ZsGV8T444FN
S4yK/aSRv3eAKkkJm5TUxbs3crATVt3JYusMr5W4wHvRVyDe0DlulSdW4EUEklMP
iPat/jwlDZRvZueio3wJoOhZXnl8E8EfnuYtlNONIB1nYGdUHD9xeNyKSPr4zTEp
brjvSw0l5G88LmQOROQBDbTDknAcIQwsFT1mf9Bt+N9LK14r95GWRmL3ZtfbrJn4
ZEfkOjl0Abv6gET4sQOXv0KioUdEJwzFCwKFLZVcuOrscmcHBOhgD3EruVvprIJ0
wZ3z1wIDAQABo1AwTjAdBgNVHQ4EFgQUmQwaPsD+ylVUUsUXMAYpUlnVbNwwHwYD
VR0jBBgwFoAUmQwaPsD+ylVUUsUXMAYpUlnVbNwwDAYDVR0TBAUwAwEB/zANBgkq
hkiG9w0BAQsFAAOCAQEASyl6BMpnZhJlirDL84/RkVeVjBkr7x68UFAblmKjgfGg
pRbYPNSld0IrfZ4pcrDAUkg9WJb0Zxuh0oYiV+RjdW/6s5mF/qiSv8V60xb2myRd
z90ZGfhB5SAECI5zfIZSmsMjOEjKjuz8S26aEtJe8Vq7GF2P7/889lfNXrbvIkZX
HQpx2P+T07zy++6Ca/K2vmWcf1a+GrN+o0nZTYbz/2r/JJwXdWqT1ZmtEA9GNwvZ
J8HhgvspgjgVP/EURUUhOaQ8zfhriU5CJAIuhMhzW7oOBPHxxtxme3auAfxi5zpK
wRNluCayrrjhy2I8mABRnBqgMwAQUIrgk9IU6SyQxw==
-----END CERTIFICATE-----

3218
data/cacert.pem Normal file

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,27 @@
positions for those additional karts. --> positions for those additional karts. -->
<karts max-number="20"/> <karts max-number="20"/>
<!-- Everything related to hardware configuration.
url : The server used for reporting statistics to.
// TODO change new-stats to stats before release-->
<HardwareReportServer url="https://new-stats.supertuxkart.net" />>
<!-- Everything related to online play.
url: The server used for online multiplayer.
server-version : Version of the server API to use. -->
<OnlineServer
url="https://online.supertuxkart.net/api/"
server-version="2"
/>
<!-- Addon and news related settings
url : The server used for addon.
allow-news-redirects : If true we allow all the server urls to be redirected by the addons news.xml file-->
<AddonServer
url="https://online.supertuxkart.net/dl/xml"
allow-news-redirects="true"
/>
<!-- Scores are the number of points given when the race ends. --> <!-- Scores are the number of points given when the race ends. -->
<grand-prix> <grand-prix>
<!-- Establish the distribution of points in GP. <!-- Establish the distribution of points in GP.
@ -157,7 +178,7 @@
<minimap size="180.0" ai-icon="16.0" player-icon="20.0"/> <minimap size="180.0" ai-icon="16.0" player-icon="20.0"/>
<urls donate="https://supertuxkart.net/Donate" <urls donate="https://supertuxkart.net/Donate"
password-reset="http://addons.supertuxkart.net/password-reset.php" /> password-reset="https://online.supertuxkart.net/password-reset.php" />
<!-- Skidmark data: maximum number of skid marks, and <!-- Skidmark data: maximum number of skid marks, and
time for skidmarks to fade out. Maximum number will over time for skidmarks to fade out. Maximum number will over

View File

@ -611,7 +611,8 @@ void AddonsManager::saveInstalled()
xml_installed << "<?xml version=\"1.0\"?>" << std::endl; xml_installed << "<?xml version=\"1.0\"?>" << std::endl;
// Get server address from config // Get server address from config
std::string server = UserConfigParams::m_server_addons; const std::string server = stk_config->m_server_addons;
// Find the third slash (end of the domain) // Find the third slash (end of the domain)
std::string::size_type index = server.find('/'); std::string::size_type index = server.find('/');
index = server.find('/', index + 2) + 1; // Omit one slash index = server.find('/', index + 2) + 1; // Omit one slash

View File

@ -20,6 +20,7 @@
#include "addons/news_manager.hpp" #include "addons/news_manager.hpp"
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "config/stk_config.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "online/http_request.hpp" #include "online/http_request.hpp"
#include "online/request_manager.hpp" #include "online/request_manager.hpp"
@ -167,7 +168,6 @@ void* NewsManager::downloadNews(void *obj)
// We need a new object, since the state of the old // We need a new object, since the state of the old
// download request is now done. // download request is now done.
download_req = new HTTPRequest("news.xml"); download_req = new HTTPRequest("news.xml");
UserConfigParams::m_server_addons.revertToDefaults();
// make sure the new server address is actually used // make sure the new server address is actually used
download_req->setAddonsURL("news.xml"); download_req->setAddonsURL("news.xml");
@ -225,25 +225,47 @@ void* NewsManager::downloadNews(void *obj)
*/ */
void NewsManager::checkRedirect(const XMLNode *xml) void NewsManager::checkRedirect(const XMLNode *xml)
{ {
std::string new_server; if (stk_config->m_allow_news_redirects)
int result = xml->get("redirect", &new_server); {
if(result==1 && new_server!="") // NOTE: Before 0.10 there were just two redirect attributes
// "redirect" - addons server (contains /dl/xml/ path)
// "hw-report-server" - hardware report server
// Redirect for the new addons server
std::string new_addons_server;
if (xml->get("redirect-server-addons", &new_addons_server) == 1 && !new_addons_server.empty())
{ {
if (UserConfigParams::logAddons()) if (UserConfigParams::logAddons())
{ {
Log::info("[Addons]", "Current server: '%s'\n [Addons] New server: '%s'", Log::info("[Addons]", "Current addons server: '%s'\n [Addons] New addons server: '%s'",
UserConfigParams::m_server_addons.c_str(), new_server.c_str()); stk_config->m_server_addons.c_str(), new_addons_server.c_str());
} }
UserConfigParams::m_server_addons = new_server; stk_config->m_server_addons = new_addons_server;
} }
std::string hw_report_server; // Redirect for the API server
if(xml->get("hw-report-server", &hw_report_server)==1 && hw_report_server.size()>0) std::string new_api_server;
if (xml->get("redirect-server-api", &new_api_server) == 1 && !new_api_server.empty())
{ {
Log::info("hw report", "New server at '%s'.", hw_report_server.c_str()); if (UserConfigParams::logAddons())
UserConfigParams::m_server_hw_report = hw_report_server; {
Log::info("[Addons]", "Current API server: '%s'\n [Addons] New API server: '%s'",
stk_config->m_server_api.c_str(), new_api_server.c_str());
}
stk_config->m_server_api = new_api_server;
} }
// Redirect for the hardware report server
std::string new_hardware_report_server;
if (xml->get("redirect-server-hardware-report", &new_hardware_report_server) == 1 && !new_hardware_report_server.empty())
{
Log::info("hw report", "Current hardware report server: '%s'\n [hw report] New hardware report server: '%s'",
stk_config->m_server_hardware_report.c_str(), new_hardware_report_server.c_str());
stk_config->m_server_hardware_report = new_hardware_report_server;
}
}
// Update menu/game polling interval
float polling; float polling;
if (xml->get("menu-polling-interval", &polling)) if (xml->get("menu-polling-interval", &polling))
{ {

View File

@ -24,6 +24,7 @@
#include "config/hardware_stats.hpp" #include "config/hardware_stats.hpp"
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "config/stk_config.hpp"
#include "graphics/central_settings.hpp" #include "graphics/central_settings.hpp"
#include "graphics/glwrap.hpp" #include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
@ -398,7 +399,8 @@ void reportHardwareStats()
request->addParameter("type", "hwdetect"); request->addParameter("type", "hwdetect");
request->addParameter("version", report_version); request->addParameter("version", report_version);
request->addParameter("data", json.toString()); request->addParameter("data", json.toString());
request->setURL((std::string)UserConfigParams::m_server_hw_report+"/upload/v1/"); const std::string request_url = stk_config->m_server_hardware_report + "/upload/v1/";
request->setURL(request_url);
//request->setURL("http://127.0.0.1:8000/upload/v1/"); //request->setURL("http://127.0.0.1:8000/upload/v1/");
request->queue(); request->queue();
#endif // !SERVER_ONLY #endif // !SERVER_ONLY

View File

@ -266,6 +266,23 @@ void STKConfig::getAllData(const XMLNode * root)
if(const XMLNode *kart_node = root->getNode("karts")) if(const XMLNode *kart_node = root->getNode("karts"))
kart_node->get("max-number", &m_max_karts); kart_node->get("max-number", &m_max_karts);
if (const XMLNode *node = root->getNode("HardwareReportServer"))
{
node->get("url", &m_server_hardware_report);
}
if (const XMLNode *node = root->getNode("OnlineServer"))
{
node->get("url", &m_server_api);
node->get("server-version", &m_server_api_version);
}
if (const XMLNode *node = root->getNode("AddonServer"))
{
node->get("url", &m_server_addons);
node->get("allow-news-redirects", &m_allow_news_redirects);
}
if(const XMLNode *gp_node = root->getNode("grand-prix")) if(const XMLNode *gp_node = root->getNode("grand-prix"))
{ {
for(unsigned int i=0; i<gp_node->getNumNodes(); i++) for(unsigned int i=0; i<gp_node->getNumNodes(); i++)

View File

@ -214,6 +214,21 @@ public:
m_snb_min_adjust_speed, m_snb_max_adjust_time, m_snb_min_adjust_speed, m_snb_max_adjust_time,
m_snb_adjust_length_threshold; m_snb_adjust_length_threshold;
/** URL for the server used for the API multiplayer. */
std::string m_server_api;
/** Version of the server API to use */
uint32_t m_server_api_version = 0;
/** URL for the server used for the addons management. */
std::string m_server_addons;
/** URL for the server used for hardware reporting statistics */
std::string m_server_hardware_report;
/** If true we allow all the server urls to be redirected by the news.xml. */
bool m_allow_news_redirects = true;
private: private:
/** True if stk_config has been loaded. This is necessary if the /** True if stk_config has been loaded. This is necessary if the
* --stk-config command line parameter has been specified to avoid * --stk-config command line parameter has been specified to avoid

View File

@ -953,12 +953,6 @@ namespace UserConfigParams
PARAM_DEFAULT( IntUserConfigParam(0, "random-identifier", &m_hw_report_group, PARAM_DEFAULT( IntUserConfigParam(0, "random-identifier", &m_hw_report_group,
"A random number to avoid duplicated reports.") ); "A random number to avoid duplicated reports.") );
PARAM_PREFIX StringUserConfigParam m_server_hw_report
PARAM_DEFAULT( StringUserConfigParam( "http://addons.supertuxkart.net:8080",
"hw-report-server",
&m_hw_report_group,
"The server used for reporting statistics to."));
PARAM_PREFIX BoolUserConfigParam m_hw_report_enable PARAM_PREFIX BoolUserConfigParam m_hw_report_enable
PARAM_DEFAULT( BoolUserConfigParam( true, PARAM_DEFAULT( BoolUserConfigParam( true,
"hw-report-enabled", "hw-report-enabled",
@ -972,35 +966,11 @@ namespace UserConfigParams
"Always show the login screen even if last player's session was saved.")); "Always show the login screen even if last player's session was saved."));
// ---- Online gameplay related
PARAM_PREFIX GroupUserConfigParam m_online_group
PARAM_DEFAULT( GroupUserConfigParam("OnlineServer",
"Everything related to online play.") );
PARAM_PREFIX StringUserConfigParam m_server_multiplayer
PARAM_DEFAULT( StringUserConfigParam( "https://addons.supertuxkart.net/api/",
"server_multiplayer",
&m_online_group,
"The server used for online multiplayer."));
PARAM_PREFIX IntUserConfigParam m_server_version
PARAM_DEFAULT( IntUserConfigParam( 2,
"server-version",
&m_online_group,
"Version of the server API to use."));
// ---- Addon server related entries // ---- Addon server related entries
PARAM_PREFIX GroupUserConfigParam m_addon_group PARAM_PREFIX GroupUserConfigParam m_addon_group
PARAM_DEFAULT( GroupUserConfigParam("AddonServer", PARAM_DEFAULT( GroupUserConfigParam("AddonServer",
"Addon and news related settings") ); "Addon and news related settings") );
PARAM_PREFIX StringUserConfigParam m_server_addons
PARAM_DEFAULT( StringUserConfigParam("http://addons.supertuxkart.net/dl/xml",
"server_addons",
&m_addon_group,
"The server used for addon."));
PARAM_PREFIX TimeUserConfigParam m_news_last_updated PARAM_PREFIX TimeUserConfigParam m_news_last_updated
PARAM_DEFAULT( TimeUserConfigParam(0, "news_last_updated", PARAM_DEFAULT( TimeUserConfigParam(0, "news_last_updated",
&m_addon_group, &m_addon_group,

View File

@ -348,8 +348,9 @@ void FileManager::init()
for(int i=0;i<(int)dirs.size(); i++) for(int i=0;i<(int)dirs.size(); i++)
pushMusicSearchPath(dirs[i]); pushMusicSearchPath(dirs[i]);
} }
m_cert_location = m_file_system->getAbsolutePath(
getAsset("addons.supertuxkart.net.pem").c_str()).c_str(); m_cert_bundle_location = m_file_system->getAbsolutePath(
getAsset("cacert.pem").c_str()).c_str();
} // init } // init
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1483,4 +1484,3 @@ bool FileManager::fileIsNewer(const std::string& f1, const std::string& f2) cons
stat(f2.c_str(), &stat2); stat(f2.c_str(), &stat2);
return stat1.st_mtime > stat2.st_mtime; return stat1.st_mtime > stat2.st_mtime;
} // fileIsNewer } // fileIsNewer

View File

@ -102,7 +102,8 @@ private:
/** Directory where user-defined grand prix are stored. */ /** Directory where user-defined grand prix are stored. */
std::string m_gp_dir; std::string m_gp_dir;
std::string m_cert_location; /** Location of the certificate bundle. */
std::string m_cert_bundle_location;
std::vector<TextureSearchPath> m_texture_search_path; std::vector<TextureSearchPath> m_texture_search_path;
@ -230,7 +231,9 @@ public:
{ {
return m_subdir_name[SHADER]; return m_subdir_name[SHADER];
} }
const std::string& getCertLocation() const { return m_cert_location; }
const std::string& getCertBundleLocation() const { return m_cert_bundle_location; }
}; // FileManager }; // FileManager
extern FileManager* file_manager; extern FileManager* file_manager;

View File

@ -17,6 +17,7 @@
#include "online/http_request.hpp" #include "online/http_request.hpp"
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "config/stk_config.hpp"
#include "online/request_manager.hpp" #include "online/request_manager.hpp"
#include "utils/constants.hpp" #include "utils/constants.hpp"
#include "utils/translation.hpp" #include "utils/translation.hpp"
@ -95,10 +96,10 @@ namespace Online
m_parameters = ""; m_parameters = "";
m_curl_code = CURLE_OK; m_curl_code = CURLE_OK;
m_progress.setAtomic(0); m_progress.setAtomic(0);
if (m_http_header == NULL) if (m_http_header == nullptr)
{ {
m_http_header = curl_slist_append(m_http_header, std::string Host = "Host: " + StringUtils::getHostNameFromURL(stk_config->m_server_api);
"Host: addons.supertuxkart.net"); m_http_header = curl_slist_append(m_http_header, Host.c_str());
} }
m_disable_sending_log = false; m_disable_sending_log = false;
} // init } // init
@ -114,10 +115,10 @@ namespace Online
const std::string &action) const std::string &action)
{ {
// Old (0.8.1) API: send to client-user.php, and add action as a parameter // Old (0.8.1) API: send to client-user.php, and add action as a parameter
if(UserConfigParams::m_server_version==1) if (stk_config->m_server_api_version == 1)
{ {
setURL( (std::string)UserConfigParams::m_server_multiplayer + const std::string final_url = stk_config->m_server_api + "client-user.php";
"client-user.php" ); setURL(final_url);
if (action == "change-password") if (action == "change-password")
addParameter("action", "change_password"); addParameter("action", "change_password");
else if (action == "recover") else if (action == "recover")
@ -127,12 +128,12 @@ namespace Online
} }
else else
{ {
setURL( const std::string final_url = stk_config->m_server_api +
(std::string)UserConfigParams::m_server_multiplayer + + "v" + StringUtils::toString(stk_config->m_server_api_version)
+"v"+StringUtils::toString(UserConfigParams::m_server_version) + "/" + path // eg: /user/, /server/
+ "/" + path + // eg: /user/, /server/ + action + "/"; // eg: connect/, pool/, get-server-list/
action + "/" // eg: connect/, pool/, get-server-list/
); setURL(final_url);
} }
} // setServerURL } // setServerURL
@ -143,7 +144,7 @@ namespace Online
*/ */
void HTTPRequest::setAddonsURL(const std::string& path) void HTTPRequest::setAddonsURL(const std::string& path)
{ {
setURL((std::string)UserConfigParams::m_server_addons + "/" + path); setURL(stk_config->m_server_addons + "/" + path);
} // set AddonsURL } // set AddonsURL
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -169,7 +170,7 @@ namespace Online
} }
curl_easy_setopt(m_curl_session, CURLOPT_URL, m_url.c_str()); curl_easy_setopt(m_curl_session, CURLOPT_URL, m_url.c_str());
curl_easy_setopt(m_curl_session, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(m_curl_session, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(m_curl_session, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(m_curl_session, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSDATA, this); curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSDATA, this);
curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSFUNCTION, curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSFUNCTION,
@ -179,15 +180,10 @@ namespace Online
curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_TIME, 20); curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_TIME, 20);
curl_easy_setopt(m_curl_session, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(m_curl_session, CURLOPT_NOSIGNAL, 1);
//curl_easy_setopt(m_curl_session, CURLOPT_VERBOSE, 1L); //curl_easy_setopt(m_curl_session, CURLOPT_VERBOSE, 1L);
if (m_url.substr(0, 8) == "https://")
{
// https, load certificate info // https, load certificate info
assert(m_http_header != NULL); const std::string& ci = file_manager->getCertBundleLocation();
curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, CURLcode error = curl_easy_setopt(m_curl_session, CURLOPT_CAINFO, ci.c_str());
m_http_header);
const std::string& ci = file_manager->getCertLocation();
CURLcode error = curl_easy_setopt(m_curl_session, CURLOPT_CAINFO,
ci.c_str());
if (error != CURLE_OK) if (error != CURLE_OK)
{ {
Log::error("HTTPRequest", "Error setting CAINFO to '%s'", Log::error("HTTPRequest", "Error setting CAINFO to '%s'",
@ -195,13 +191,11 @@ namespace Online
Log::error("HTTPRequest", "Error: '%s'.", error, Log::error("HTTPRequest", "Error: '%s'.", error,
curl_easy_strerror(error)); curl_easy_strerror(error));
} }
assert(m_http_header != nullptr);
curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, m_http_header);
curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 1L); curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 1L);
#ifdef __APPLE__ curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYHOST, 2L);
curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYHOST, 0L);
#else
curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYHOST, 1L);
#endif
}
} // prepareOperation } // prepareOperation
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -958,6 +958,34 @@ namespace StringUtils
return out; return out;
} }
// ------------------------------------------------------------------------
std::string getHostNameFromURL(const std::string& url)
{
// Not even a valid URL
if (url.length() < 8)
return "";
// protocol is substr(0, first_color_position)
const size_t first_colon_position = url.find_first_of(":");
if (first_colon_position == std::string::npos)
return "";
// skip ://
const std::string url_without_protocol = url.substr(first_colon_position + 3);
// Find end with port
const size_t port_colon_position = url_without_protocol.find_first_of(":");
if (port_colon_position != std::string::npos)
return url_without_protocol.substr(0, port_colon_position);
// Find end with path
const size_t slash_position = url_without_protocol.find_first_of("/");
if (slash_position != std::string::npos)
return url_without_protocol.substr(0, slash_position);
return url_without_protocol;
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Breaks the text so that each line is smaller than max_width with the current settings. /** Breaks the text so that each line is smaller than max_width with the current settings.
* The result is put into output, a vector of strings, with each line having its own string */ * The result is put into output, a vector of strings, with each line having its own string */

View File

@ -271,6 +271,15 @@ namespace StringUtils
#endif #endif
return uagent; return uagent;
} }
/**
* Returns the hostname part of an url (if any)
*
* Example https://online.supertuxkart.net/
*
*/
std::string getHostNameFromURL(const std::string& url);
} // namespace StringUtils } // namespace StringUtils
#endif #endif