summaryrefslogtreecommitdiff
path: root/src/network/network.cpp
diff options
context:
space:
mode:
authorPatric Stout <truebrain@openttd.org>2021-07-11 12:08:03 +0200
committerPatric Stout <github@truebrain.nl>2021-07-11 20:38:42 +0200
commit1baec41542780cf4fc898df7d2fc9925d823fb44 (patch)
tree57aa8bc38997fc9d39a4ae66af7b912712e1830e /src/network/network.cpp
parentcee8174d02e38542548fc74de93450cfebefaa91 (diff)
downloadopenttd-1baec41542780cf4fc898df7d2fc9925d823fb44.tar.xz
Change: groundwork to allow ServerAddress to use invite codes
Normally TCPConnecter will do a DNS resolving of the connection_string and connect to it. But for SERVER_ADDRESS_INVITE_CODE this is different: the Game Coordinator does the "resolving". This means we need to allow TCPConnecter to not setup a connection and allow it to be told when a connection has been setup by an external (to TCPConnecter) part of the code. We do this by telling the (active) socket for the connection. This means the rest of the code doesn't need to know the TCPConnecter is not doing a simple resolve+connect. The rest of the code only cares the connection is established; not how it was established.
Diffstat (limited to 'src/network/network.cpp')
-rw-r--r--src/network/network.cpp59
1 files changed, 36 insertions, 23 deletions
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 4e48ce351..3a33e5096 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -453,6 +453,41 @@ static void CheckPauseOnJoin()
}
/**
+ * Parse the company part ("#company" postfix) of a connecting string.
+ * @param connection_string The string with the connection data.
+ * @param company_id The company ID to set, if available.
+ * @return A std::string_view into the connection string without the company part.
+ */
+std::string_view ParseCompanyFromConnectionString(const std::string &connection_string, CompanyID *company_id)
+{
+ std::string_view ip = connection_string;
+ if (company_id == nullptr) return ip;
+
+ size_t offset = ip.find_last_of('#');
+ if (offset != std::string::npos) {
+ std::string_view company_string = ip.substr(offset + 1);
+ ip = ip.substr(0, offset);
+
+ uint8 company_value;
+ auto [_, err] = std::from_chars(company_string.data(), company_string.data() + company_string.size(), company_value);
+ if (err == std::errc()) {
+ if (company_value != COMPANY_NEW_COMPANY && company_value != COMPANY_SPECTATOR) {
+ if (company_value > MAX_COMPANIES || company_value == 0) {
+ *company_id = COMPANY_SPECTATOR;
+ } else {
+ /* "#1" means the first company, which has index 0. */
+ *company_id = (CompanyID)(company_value - 1);
+ }
+ } else {
+ *company_id = (CompanyID)company_value;
+ }
+ }
+ }
+
+ return ip;
+}
+
+/**
* Converts a string to ip/port/company
* Format: IP:port#company
*
@@ -469,29 +504,7 @@ static void CheckPauseOnJoin()
*/
std::string_view ParseFullConnectionString(const std::string &connection_string, uint16 &port, CompanyID *company_id)
{
- std::string_view ip = connection_string;
- if (company_id != nullptr) {
- size_t offset = ip.find_last_of('#');
- if (offset != std::string::npos) {
- std::string_view company_string = ip.substr(offset + 1);
- ip = ip.substr(0, offset);
-
- uint8 company_value;
- auto [_, err] = std::from_chars(company_string.data(), company_string.data() + company_string.size(), company_value);
- if (err == std::errc()) {
- if (company_value != COMPANY_NEW_COMPANY && company_value != COMPANY_SPECTATOR) {
- if (company_value > MAX_COMPANIES || company_value == 0) {
- *company_id = COMPANY_SPECTATOR;
- } else {
- /* "#1" means the first company, which has index 0. */
- *company_id = (CompanyID)(company_value - 1);
- }
- } else {
- *company_id = (CompanyID)company_value;
- }
- }
- }
- }
+ std::string_view ip = ParseCompanyFromConnectionString(connection_string, company_id);
size_t port_offset = ip.find_last_of(':');
size_t ipv6_close = ip.find_last_of(']');