OpenTTD Source: src/network/network_coordinator.cpp Source File

OpenTTD Source 15.3

network_coordinator.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "../stdafx.h"
11#include "../debug.h"
12#include "../error.h"
13#include "../rev.h"
14#include "../settings_type.h"
15#include "../strings_func.h"
16#include "../window_func.h"
17#include "../window_type.h"
18#include "network.h"
19#include "network_coordinator.h"
20#include "network_gamelist.h"
21#include "network_gui.h"
22#include "network_internal.h"
23#include "network_server.h"
24#include "network_stun.h"
25#include "table/strings.h"
26
27#include "../safeguards.h"
28
29 static const auto NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES = std::chrono::seconds(30);
30 ClientNetworkCoordinatorSocketHandler _network_coordinator_client;
31 ConnectionType _network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
32std::string _network_server_invite_code = "";
33
35 class NetworkDirectConnecter : public TCPConnecter {
36private:
37 std::string token;
38 uint8_t tracking_number;
39
40public:
48 NetworkDirectConnecter(std::string_view hostname, uint16_t port, std::string &&token, uint8_t tracking_number) : TCPConnecter(hostname, port), token(std::move(token)), tracking_number(tracking_number) {}
49
50 void OnFailure() override
51 {
52 _network_coordinator_client.ConnectFailure(this->token, this->tracking_number);
53 }
54
55 void OnConnect(SOCKET s) override
56 {
57 NetworkAddress address = NetworkAddress::GetPeerAddress(s);
58 _network_coordinator_client.ConnectSuccess(this->token, s, address);
59 }
60};
61
63 class NetworkReuseStunConnecter : public TCPConnecter {
64private:
65 std::string token;
66 uint8_t tracking_number;
67 uint8_t family;
68
69public:
79 NetworkReuseStunConnecter(std::string_view hostname, uint16_t port, const NetworkAddress &bind_address, std::string &&token, uint8_t tracking_number, uint8_t family) :
80 TCPConnecter(hostname, port, bind_address),
81 token(std::move(token)),
82 tracking_number(tracking_number),
83 family(family)
84 {
85 }
86
87 void OnFailure() override
88 {
89 /* Close the STUN connection too, as it is no longer of use. */
90 _network_coordinator_client.CloseStunHandler(this->token, this->family);
91
92 _network_coordinator_client.ConnectFailure(this->token, this->tracking_number);
93 }
94
95 void OnConnect(SOCKET s) override
96 {
97 NetworkAddress address = NetworkAddress::GetPeerAddress(s);
98 _network_coordinator_client.ConnectSuccess(this->token, s, address);
99 }
100};
101
103 class NetworkCoordinatorConnecter : public TCPConnecter {
104public:
109 NetworkCoordinatorConnecter(std::string_view connection_string) : TCPConnecter(connection_string, NETWORK_COORDINATOR_SERVER_PORT) {}
110
111 void OnFailure() override
112 {
113 _network_coordinator_client.connecting = false;
114 _network_coordinator_client.CloseConnection(true);
115 }
116
117 void OnConnect(SOCKET s) override
118 {
119 assert(_network_coordinator_client.sock == INVALID_SOCKET);
120
121 _network_coordinator_client.sock = s;
122 _network_coordinator_client.last_activity = std::chrono::steady_clock::now();
123 _network_coordinator_client.connecting = false;
124 }
125};
126
127 bool ClientNetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet &p)
128{
129 NetworkCoordinatorErrorType error = (NetworkCoordinatorErrorType)p.Recv_uint8();
130 std::string detail = p.Recv_string(NETWORK_ERROR_DETAIL_LENGTH);
131 Debug(net, 9, "Coordinator::Receive_GC_ERROR({}, {})", error, detail);
132
133 switch (error) {
134 case NETWORK_COORDINATOR_ERROR_UNKNOWN:
135 this->CloseConnection();
136 return false;
137
138 case NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED:
139 ShowErrorMessage(GetEncodedString(STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED), {}, WL_ERROR);
140
141 /* To prevent that we constantly try to reconnect, switch to local game. */
142 _settings_client.network.server_game_type = SERVER_GAME_TYPE_LOCAL;
143
144 this->CloseConnection();
145 return false;
146
147 case NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE: {
148 auto connecter_pre_it = this->connecter_pre.find(detail);
149 if (connecter_pre_it != this->connecter_pre.end()) {
150 connecter_pre_it->second->SetFailure();
151 this->connecter_pre.erase(connecter_pre_it);
152 }
153
154 /* Mark the server as offline. */
155 NetworkGame *item = NetworkGameListAddItem(detail);
156 item->status = NGLS_OFFLINE;
157
158 UpdateNetworkGameWindow();
159 return true;
160 }
161
162 case NETWORK_COORDINATOR_ERROR_REUSE_OF_INVITE_CODE:
163 ShowErrorMessage(GetEncodedString(STR_NETWORK_ERROR_COORDINATOR_REUSE_OF_INVITE_CODE), {}, WL_ERROR);
164
165 /* To prevent that we constantly battle for the same invite-code, switch to local game. */
166 _settings_client.network.server_game_type = SERVER_GAME_TYPE_LOCAL;
167
168 this->CloseConnection();
169 return false;
170
171 default:
172 Debug(net, 0, "Invalid error type {} received from Game Coordinator", error);
173 this->CloseConnection();
174 return false;
175 }
176}
177
178 bool ClientNetworkCoordinatorSocketHandler::Receive_GC_REGISTER_ACK(Packet &p)
179{
180 /* Schedule sending an update. */
181 this->next_update = std::chrono::steady_clock::now();
182
183 _settings_client.network.server_invite_code = p.Recv_string(NETWORK_INVITE_CODE_LENGTH);
184 _settings_client.network.server_invite_code_secret = p.Recv_string(NETWORK_INVITE_CODE_SECRET_LENGTH);
185 _network_server_connection_type = (ConnectionType)p.Recv_uint8();
186 Debug(net, 9, "Coordinator::Receive_GC_REGISTER_ACK({}, {})", _settings_client.network.server_invite_code, _network_server_connection_type);
187
188 if (_network_server_connection_type == CONNECTION_TYPE_ISOLATED) {
189 ShowErrorMessage(
190 GetEncodedString(STR_NETWORK_ERROR_COORDINATOR_ISOLATED),
191 GetEncodedString(STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL),
192 WL_ERROR);
193 }
194
195 /* Users can change the invite code in the settings, but this has no effect
196 * on the invite code as assigned by the server. So
197 * _network_server_invite_code contains the current invite code,
198 * and _settings_client.network.server_invite_code contains the one we will
199 * attempt to re-use when registering again. */
200 _network_server_invite_code = _settings_client.network.server_invite_code;
201
202 SetWindowDirty(WC_CLIENT_LIST, 0);
203
204 if (_network_dedicated) {
205 std::string connection_type;
206 switch (_network_server_connection_type) {
207 case CONNECTION_TYPE_ISOLATED: connection_type = "Remote players can't connect"; break;
208 case CONNECTION_TYPE_DIRECT: connection_type = "Public"; break;
209 case CONNECTION_TYPE_STUN: connection_type = "Behind NAT"; break;
210 case CONNECTION_TYPE_TURN: connection_type = "Via relay"; break;
211
212 case CONNECTION_TYPE_UNKNOWN: // Never returned from Game Coordinator.
213 default: connection_type = "Unknown"; break; // Should never happen, but don't fail if it does.
214 }
215
216 std::string game_type;
217 switch (_settings_client.network.server_game_type) {
218 case SERVER_GAME_TYPE_INVITE_ONLY: game_type = "Invite only"; break;
219 case SERVER_GAME_TYPE_PUBLIC: game_type = "Public"; break;
220
221 case SERVER_GAME_TYPE_LOCAL: // Impossible to register local servers.
222 default: game_type = "Unknown"; break; // Should never happen, but don't fail if it does.
223 }
224
225 Debug(net, 3, "----------------------------------------");
226 Debug(net, 3, "Your server is now registered with the Game Coordinator:");
227 Debug(net, 3, " Game type: {}", game_type);
228 Debug(net, 3, " Connection type: {}", connection_type);
229 Debug(net, 3, " Invite code: {}", _network_server_invite_code);
230 Debug(net, 3, "----------------------------------------");
231 } else {
232 Debug(net, 3, "Game Coordinator registered our server with invite code '{}'", _network_server_invite_code);
233 }
234
235 return true;
236}
237
238 bool ClientNetworkCoordinatorSocketHandler::Receive_GC_LISTING(Packet &p)
239{
240 uint8_t servers = p.Recv_uint16();
241 Debug(net, 9, "Coordinator::Receive_GC_LISTING({})", servers);
242
243 /* End of list; we can now remove all expired items from the list. */
244 if (servers == 0) {
245 NetworkGameListRemoveExpired();
246 return true;
247 }
248
249 for (; servers > 0; servers--) {
250 std::string connection_string = p.Recv_string(NETWORK_HOSTNAME_PORT_LENGTH);
251
252 /* Now we know the connection string, we can add it to our list. */
253 NetworkGame *item = NetworkGameListAddItem(connection_string);
254
255 /* Clear any existing GRFConfig chain. */
256 ClearGRFConfigList(item->info.grfconfig);
257 /* Read the NetworkGameInfo from the packet. */
258 DeserializeNetworkGameInfo(p, item->info, &this->newgrf_lookup_table);
259 /* Check for compatibility with the client. */
260 CheckGameCompatibility(item->info);
261 /* Mark server as online. */
262 item->status = NGLS_ONLINE;
263 /* Mark the item as up-to-date. */
264 item->version = _network_game_list_version;
265 }
266
267 UpdateNetworkGameWindow();
268 return true;
269}
270
271 bool ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECTING(Packet &p)
272{
273 std::string token = p.Recv_string(NETWORK_TOKEN_LENGTH);
274 std::string invite_code = p.Recv_string(NETWORK_INVITE_CODE_LENGTH);
275 Debug(net, 9, "Coordinator::Receive_GC_CONNECTING({}, {})", token, invite_code);
276
277 /* Find the connecter based on the invite code. */
278 auto connecter_pre_it = this->connecter_pre.find(invite_code);
279 if (connecter_pre_it == this->connecter_pre.end()) {
280 this->CloseConnection();
281 return false;
282 }
283
284 /* Now store it based on the token. */
285 this->connecter[token] = {invite_code, connecter_pre_it->second};
286 this->connecter_pre.erase(connecter_pre_it);
287
288 return true;
289}
290
291 bool ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECT_FAILED(Packet &p)
292{
293 std::string token = p.Recv_string(NETWORK_TOKEN_LENGTH);
294 Debug(net, 9, "Coordinator::Receive_GC_CONNECT_FAILED({})", token);
295 this->CloseToken(token);
296
297 return true;
298}
299
300 bool ClientNetworkCoordinatorSocketHandler::Receive_GC_DIRECT_CONNECT(Packet &p)
301{
302 std::string token = p.Recv_string(NETWORK_TOKEN_LENGTH);
303 uint8_t tracking_number = p.Recv_uint8();
304 std::string hostname = p.Recv_string(NETWORK_HOSTNAME_LENGTH);
305 uint16_t port = p.Recv_uint16();
306 Debug(net, 9, "Coordinator::Receive_GC_DIRECT_CONNECT({}, {}, {}, {})", token, tracking_number, hostname, port);
307
308 /* Ensure all other pending connection attempts are killed. */
309 if (this->game_connecter != nullptr) {
310 this->game_connecter->Kill();
311 this->game_connecter = nullptr;
312 }
313
314 this->game_connecter = TCPConnecter::Create<NetworkDirectConnecter>(hostname, port, std::move(token), tracking_number);
315 return true;
316}
317
318 bool ClientNetworkCoordinatorSocketHandler::Receive_GC_STUN_REQUEST(Packet &p)
319{
320 std::string token = p.Recv_string(NETWORK_TOKEN_LENGTH);
321 Debug(net, 9, "Coordinator::Receive_GC_STUN_REQUEST({})", token);
322
323 this->stun_handlers[token][AF_INET6] = ClientNetworkStunSocketHandler::Stun(token, AF_INET6);
324 this->stun_handlers[token][AF_INET] = ClientNetworkStunSocketHandler::Stun(token, AF_INET);
325 return true;
326}
327
328 bool ClientNetworkCoordinatorSocketHandler::Receive_GC_STUN_CONNECT(Packet &p)
329{
330 std::string token = p.Recv_string(NETWORK_TOKEN_LENGTH);
331 uint8_t tracking_number = p.Recv_uint8();
332 uint8_t family = p.Recv_uint8();
333 std::string host = p.Recv_string(NETWORK_HOSTNAME_PORT_LENGTH);
334 uint16_t port = p.Recv_uint16();
335
336 /* Check if we know this token. */
337 auto stun_it = this->stun_handlers.find(token);
338 if (stun_it == this->stun_handlers.end()) return true;
339 auto family_it = stun_it->second.find(family);
340 if (family_it == stun_it->second.end()) return true;
341
342 /* Ensure all other pending connection attempts are killed. */
343 if (this->game_connecter != nullptr) {
344 this->game_connecter->Kill();
345 this->game_connecter = nullptr;
346 }
347
348 /* We now mark the connection as closed, but we do not really close the
349 * socket yet. We do this when the NetworkReuseStunConnecter is connected.
350 * This prevents any NAT to already remove the route while we create the
351 * second connection on top of the first. */
352 family_it->second->CloseConnection(false);
353
354 /* Connect to our peer from the same local address as we use for the
355 * STUN server. This means that if there is any NAT in the local network,
356 * the public ip:port is still pointing to the local address, and as such
357 * a connection can be established. */
358 this->game_connecter = TCPConnecter::Create<NetworkReuseStunConnecter>(host, port, family_it->second->local_addr, std::move(token), tracking_number, family);
359 return true;
360}
361
362 bool ClientNetworkCoordinatorSocketHandler::Receive_GC_NEWGRF_LOOKUP(Packet &p)
363{
364 this->newgrf_lookup_table_cursor = p.Recv_uint32();
365
366 uint16_t newgrfs = p.Recv_uint16();
367 Debug(net, 9, "Coordinator::Receive_GC_NEWGRF_LOOKUP({}, {})", this->newgrf_lookup_table_cursor, newgrfs);
368 for (; newgrfs> 0; newgrfs--) {
369 uint32_t index = p.Recv_uint32();
370 DeserializeGRFIdentifierWithName(p, this->newgrf_lookup_table[index]);
371 }
372 return true;
373}
374
375 bool ClientNetworkCoordinatorSocketHandler::Receive_GC_TURN_CONNECT(Packet &p)
376{
377 std::string token = p.Recv_string(NETWORK_TOKEN_LENGTH);
378 uint8_t tracking_number = p.Recv_uint8();
379 std::string ticket = p.Recv_string(NETWORK_TOKEN_LENGTH);
380 std::string connection_string = p.Recv_string(NETWORK_HOSTNAME_PORT_LENGTH);
381 Debug(net, 9, "Coordinator::Receive_GC_TURN_CONNECT({}, {}, {}, {})", token, tracking_number, ticket, connection_string);
382
383 /* Ensure all other pending connection attempts are killed. */
384 if (this->game_connecter != nullptr) {
385 this->game_connecter->Kill();
386 this->game_connecter = nullptr;
387 }
388
389 this->turn_handlers[token] = ClientNetworkTurnSocketHandler::Turn(token, tracking_number, ticket, connection_string);
390
391 if (!_network_server) {
392 auto connecter_it = this->connecter.find(token);
393 if (connecter_it == this->connecter.end()) {
394 /* Make sure we are still interested in connecting to this server. */
395 this->ConnectFailure(token, 0);
396 return true;
397 }
398
399 switch (_settings_client.network.use_relay_service) {
400 case URS_NEVER:
401 this->ConnectFailure(token, 0);
402 break;
403
404 case URS_ASK:
405 ShowNetworkAskRelay(connecter_it->second.first, std::move(connection_string), std::move(token));
406 break;
407
408 case URS_ALLOW:
409 this->StartTurnConnection(token);
410 break;
411 }
412 } else {
413 this->StartTurnConnection(token);
414 }
415
416 return true;
417}
418
419void ClientNetworkCoordinatorSocketHandler::StartTurnConnection(std::string_view token)
420{
421 auto turn_it = this->turn_handlers.find(token);
422 if (turn_it == this->turn_handlers.end()) return;
423
424 turn_it->second->Connect();
425}
426
427void ClientNetworkCoordinatorSocketHandler::Connect()
428{
429 /* We are either already connected or are trying to connect. */
430 if (this->sock != INVALID_SOCKET || this->connecting) return;
431
432 this->Reopen();
433
434 this->connecting = true;
435 this->last_activity = std::chrono::steady_clock::now();
436
437 TCPConnecter::Create<NetworkCoordinatorConnecter>(NetworkCoordinatorConnectionString());
438}
439
440 NetworkRecvStatus ClientNetworkCoordinatorSocketHandler::CloseConnection(bool error)
441{
442 NetworkCoordinatorSocketHandler::CloseConnection(error);
443
444 this->CloseSocket();
445 this->connecting = false;
446
447 _network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
448 this->next_update = {};
449
450 this->CloseAllConnections();
451
452 SetWindowDirty(WC_CLIENT_LIST, 0);
453
454 return NETWORK_RECV_STATUS_OKAY;
455}
456
460 void ClientNetworkCoordinatorSocketHandler::Register()
461{
462 _network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
463 this->next_update = {};
464
465 SetWindowDirty(WC_CLIENT_LIST, 0);
466
467 this->Connect();
468
469 auto p = std::make_unique<Packet>(this, PACKET_COORDINATOR_SERVER_REGISTER);
470 p->Send_uint8(NETWORK_COORDINATOR_VERSION);
471 p->Send_uint8(_settings_client.network.server_game_type);
472 p->Send_uint16(_settings_client.network.server_port);
473 if (_settings_client.network.server_invite_code.empty() || _settings_client.network.server_invite_code_secret.empty()) {
474 p->Send_string("");
475 p->Send_string("");
476 } else {
477 p->Send_string(_settings_client.network.server_invite_code);
478 p->Send_string(_settings_client.network.server_invite_code_secret);
479 }
480
481 Debug(net, 9, "Coordinator::SendRegister({}, {}, {})", _settings_client.network.server_game_type, _settings_client.network.server_port, _settings_client.network.server_invite_code);
482 this->SendPacket(std::move(p));
483}
484
488 void ClientNetworkCoordinatorSocketHandler::SendServerUpdate()
489{
490 Debug(net, 6, "Sending server update to Game Coordinator");
491
492 auto p = std::make_unique<Packet>(this, PACKET_COORDINATOR_SERVER_UPDATE, TCP_MTU);
493 p->Send_uint8(NETWORK_COORDINATOR_VERSION);
494 SerializeNetworkGameInfo(*p, GetCurrentNetworkServerGameInfo(), this->next_update.time_since_epoch() != std::chrono::nanoseconds::zero());
495
496 Debug(net, 9, "Coordinator::SendServerUpdate()");
497 this->SendPacket(std::move(p));
498
499 this->next_update = std::chrono::steady_clock::now() + NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES;
500}
501
505 void ClientNetworkCoordinatorSocketHandler::GetListing()
506{
507 this->Connect();
508
509 _network_game_list_version++;
510
511 auto p = std::make_unique<Packet>(this, PACKET_COORDINATOR_CLIENT_LISTING);
512 p->Send_uint8(NETWORK_COORDINATOR_VERSION);
513 p->Send_uint8(NETWORK_GAME_INFO_VERSION);
514 p->Send_string(_openttd_revision);
515 p->Send_uint32(this->newgrf_lookup_table_cursor);
516
517 Debug(net, 9, "Coordinator::SendGetListing({}, {})", _openttd_revision, this->newgrf_lookup_table_cursor);
518 this->SendPacket(std::move(p));
519}
520
526 void ClientNetworkCoordinatorSocketHandler::ConnectToServer(std::string_view invite_code, TCPServerConnecter *connecter)
527{
528 assert(invite_code.starts_with("+"));
529
530 if (this->connecter_pre.find(invite_code) != this->connecter_pre.end()) {
531 /* If someone is hammering the refresh key, one can sent out two
532 * requests for the same invite code. There isn't really a great way
533 * of handling this, so just ignore this request. */
534 connecter->SetFailure();
535 return;
536 }
537
538 /* Initially we store based on invite code; on first reply we know the
539 * token, and will start using that key instead. */
540 this->connecter_pre[std::string(invite_code)] = connecter;
541
542 this->Connect();
543
544 auto p = std::make_unique<Packet>(this, PACKET_COORDINATOR_CLIENT_CONNECT);
545 p->Send_uint8(NETWORK_COORDINATOR_VERSION);
546 p->Send_string(invite_code);
547
548 Debug(net, 9, "Coordinator::SendConnectToClient({})", invite_code);
549 this->SendPacket(std::move(p));
550}
551
557 void ClientNetworkCoordinatorSocketHandler::ConnectFailure(std::string_view token, uint8_t tracking_number)
558{
559 /* Connecter will destroy itself. */
560 this->game_connecter = nullptr;
561
562 auto p = std::make_unique<Packet>(this, PACKET_COORDINATOR_SERCLI_CONNECT_FAILED);
563 p->Send_uint8(NETWORK_COORDINATOR_VERSION);
564 p->Send_string(token);
565 p->Send_uint8(tracking_number);
566
567 Debug(net, 9, "Coordinator::SendConnectFailure({}, {})", token, tracking_number);
568 this->SendPacket(std::move(p));
569
570 /* We do not close the associated connecter here yet, as the
571 * Game Coordinator might have other methods of connecting available. */
572}
573
580 void ClientNetworkCoordinatorSocketHandler::ConnectSuccess(std::string_view token, SOCKET sock, NetworkAddress &address)
581{
582 assert(sock != INVALID_SOCKET);
583
584 /* Connecter will destroy itself. */
585 this->game_connecter = nullptr;
586
587 if (_network_server) {
588 if (!ServerNetworkGameSocketHandler::ValidateClient(sock, address)) return;
589 Debug(net, 3, "[{}] Client connected from {} on frame {}", ServerNetworkGameSocketHandler::GetName(), address.GetHostname(), _frame_counter);
590 ServerNetworkGameSocketHandler::AcceptConnection(sock, address);
591 } else {
592 /* The client informs the Game Coordinator about the success. The server
593 * doesn't have to, as it is implied by the client telling. */
594 auto p = std::make_unique<Packet>(this, PACKET_COORDINATOR_CLIENT_CONNECTED);
595 p->Send_uint8(NETWORK_COORDINATOR_VERSION);
596 p->Send_string(token);
597 Debug(net, 9, "Coordinator::SendConnectSuccess({})", token);
598 this->SendPacket(std::move(p));
599
600 /* Find the connecter; it can happen it no longer exist, in cases where
601 * we aborted the connect but the Game Coordinator was already in the
602 * processes of connecting us. */
603 auto connecter_it = this->connecter.find(token);
604 if (connecter_it != this->connecter.end()) {
605 connecter_it->second.second->SetConnected(sock);
606 this->connecter.erase(connecter_it);
607 }
608 }
609
610 /* Close all remaining connections. */
611 this->CloseToken(token);
612}
613
621 void ClientNetworkCoordinatorSocketHandler::StunResult(std::string_view token, uint8_t family, bool result)
622{
623 auto p = std::make_unique<Packet>(this, PACKET_COORDINATOR_SERCLI_STUN_RESULT);
624 p->Send_uint8(NETWORK_COORDINATOR_VERSION);
625 p->Send_string(token);
626 p->Send_uint8(family);
627 p->Send_bool(result);
628 Debug(net, 9, "Coordinator::SendStunResult({}, {}, {})", token, family, result);
629 this->SendPacket(std::move(p));
630}
631
637 void ClientNetworkCoordinatorSocketHandler::CloseStunHandler(std::string_view token, uint8_t family)
638{
639 auto stun_it = this->stun_handlers.find(token);
640 if (stun_it == this->stun_handlers.end()) return;
641
642 if (family == AF_UNSPEC) {
643 for (auto &[family, stun_handler] : stun_it->second) {
644 stun_handler->CloseConnection();
645 stun_handler->CloseSocket();
646 }
647
648 this->stun_handlers.erase(stun_it);
649 } else {
650 auto family_it = stun_it->second.find(family);
651 if (family_it == stun_it->second.end()) return;
652
653 family_it->second->CloseConnection();
654 family_it->second->CloseSocket();
655
656 stun_it->second.erase(family_it);
657 }
658}
659
664 void ClientNetworkCoordinatorSocketHandler::CloseTurnHandler(std::string_view token)
665{
666 CloseWindowByClass(WC_NETWORK_ASK_RELAY, NRWCD_HANDLED);
667
668 auto turn_it = this->turn_handlers.find(token);
669 if (turn_it == this->turn_handlers.end()) return;
670
671 turn_it->second->CloseConnection();
672 turn_it->second->CloseSocket();
673
674 /* We don't remove turn_handler here, as we can be called from within that
675 * turn_handler instance, so our object cannot be freed yet. Instead, we
676 * check later if the connection is closed, and free the object then. */
677}
678
683 void ClientNetworkCoordinatorSocketHandler::CloseToken(std::string_view token)
684{
685 /* Close all remaining STUN / TURN connections. */
686 this->CloseStunHandler(token);
687 this->CloseTurnHandler(token);
688
689 /* Close the caller of the connection attempt. */
690 auto connecter_it = this->connecter.find(token);
691 if (connecter_it != this->connecter.end()) {
692 connecter_it->second.second->SetFailure();
693 this->connecter.erase(connecter_it);
694 }
695}
696
700 void ClientNetworkCoordinatorSocketHandler::CloseAllConnections()
701{
702 /* Ensure all other pending connection attempts are also killed. */
703 if (this->game_connecter != nullptr) {
704 this->game_connecter->Kill();
705 this->game_connecter = nullptr;
706 }
707
708 /* Mark any pending connecters as failed. */
709 for (auto &[token, it] : this->connecter) {
710 this->CloseStunHandler(token);
711 this->CloseTurnHandler(token);
712 it.second->SetFailure();
713
714 /* Inform the Game Coordinator he can stop trying to connect us to the server. */
715 this->ConnectFailure(token, 0);
716 }
717 this->stun_handlers.clear();
718 this->turn_handlers.clear();
719 this->connecter.clear();
720
721 /* Also close any pending invite-code requests. */
722 for (auto &[invite_code, it] : this->connecter_pre) {
723 it->SetFailure();
724 }
725 this->connecter_pre.clear();
726}
727
732 void ClientNetworkCoordinatorSocketHandler::SendReceive()
733{
734 /* Private games are not listed via the Game Coordinator. */
735 if (_network_server && _settings_client.network.server_game_type == SERVER_GAME_TYPE_LOCAL) {
736 if (this->sock != INVALID_SOCKET) {
737 this->CloseConnection();
738 }
739 return;
740 }
741
742 static int last_attempt_backoff = 1;
743 static bool first_reconnect = true;
744
745 if (this->sock == INVALID_SOCKET) {
746 static std::chrono::steady_clock::time_point last_attempt = {};
747
748 /* Don't auto-reconnect when we are not a server. */
749 if (!_network_server) return;
750 /* Don't reconnect if we are connecting. */
751 if (this->connecting) return;
752 /* Throttle how often we try to reconnect. */
753 if (std::chrono::steady_clock::now() < last_attempt + std::chrono::seconds(1) * last_attempt_backoff) return;
754
755 last_attempt = std::chrono::steady_clock::now();
756 /* Delay reconnecting with up to 32 seconds. */
757 if (last_attempt_backoff < 32) {
758 last_attempt_backoff *= 2;
759 }
760
761 /* Do not reconnect on the first attempt, but only initialize the
762 * last_attempt variables. Otherwise after an outage all servers
763 * reconnect at the same time, potentially overwhelming the
764 * Game Coordinator. */
765 if (first_reconnect) {
766 first_reconnect = false;
767 return;
768 }
769
770 Debug(net, 1, "Connection with Game Coordinator lost; reconnecting...");
771 this->Register();
772 return;
773 }
774
775 last_attempt_backoff = 1;
776 first_reconnect = true;
777
778 if (_network_server && _network_server_connection_type != CONNECTION_TYPE_UNKNOWN && std::chrono::steady_clock::now() > this->next_update) {
779 this->SendServerUpdate();
780 }
781
782 if (!_network_server && std::chrono::steady_clock::now() > this->last_activity + IDLE_TIMEOUT) {
783 this->CloseConnection();
784 return;
785 }
786
787 if (this->CanSendReceive()) {
788 if (this->ReceivePackets()) {
789 this->last_activity = std::chrono::steady_clock::now();
790 }
791 }
792
793 this->SendPackets();
794
795 for (const auto &[token, families] : this->stun_handlers) {
796 for (const auto &[family, stun_handler] : families) {
797 stun_handler->SendReceive();
798 }
799 }
800
801 /* Check for handlers that are not connecting nor connected. Destroy those objects. */
802 for (auto turn_it = this->turn_handlers.begin(); turn_it != this->turn_handlers.end(); /* nothing */) {
803 if (turn_it->second->connect_started && turn_it->second->connecter == nullptr && !turn_it->second->IsConnected()) {
804 turn_it = this->turn_handlers.erase(turn_it);
805 } else {
806 turn_it++;
807 }
808 }
809
810 for (const auto &[token, turn_handler] : this->turn_handlers) {
811 turn_handler->SendReceive();
812 }
813}
ClientNetworkCoordinatorSocketHandler
Game Coordinator communication.
Definition network_coordinator.h:53
ClientNetworkCoordinatorSocketHandler::Receive_GC_NEWGRF_LOOKUP
bool Receive_GC_NEWGRF_LOOKUP(Packet &p) override
Game Coordinator informs the client of updates for the NewGRFs lookup table as used by the NewGRF des...
Definition network_coordinator.cpp:362
ClientNetworkCoordinatorSocketHandler::newgrf_lookup_table
GameInfoNewGRFLookupTable newgrf_lookup_table
Table to look up NewGRFs in the GC_LISTING packets.
Definition network_coordinator.h:63
ClientNetworkCoordinatorSocketHandler::Receive_GC_STUN_CONNECT
bool Receive_GC_STUN_CONNECT(Packet &p) override
Game Coordinator informs the client/server of its STUN peer (the host:ip of the other side).
Definition network_coordinator.cpp:328
ClientNetworkCoordinatorSocketHandler::Receive_GC_STUN_REQUEST
bool Receive_GC_STUN_REQUEST(Packet &p) override
Game Coordinator requests the client/server to do a STUN request to the STUN server.
Definition network_coordinator.cpp:318
ClientNetworkCoordinatorSocketHandler::CloseTurnHandler
void CloseTurnHandler(std::string_view token)
Close the TURN handler.
Definition network_coordinator.cpp:664
ClientNetworkCoordinatorSocketHandler::turn_handlers
std::map< std::string, std::unique_ptr< ClientNetworkTurnSocketHandler >, std::less<> > turn_handlers
Pending TURN handler (if any), stored by token.
Definition network_coordinator.h:59
ClientNetworkCoordinatorSocketHandler::Receive_GC_REGISTER_ACK
bool Receive_GC_REGISTER_ACK(Packet &p) override
Game Coordinator acknowledges the registration.
Definition network_coordinator.cpp:178
ClientNetworkCoordinatorSocketHandler::Register
void Register()
Register our server to receive our invite code.
Definition network_coordinator.cpp:460
ClientNetworkCoordinatorSocketHandler::ConnectToServer
void ConnectToServer(std::string_view invite_code, TCPServerConnecter *connecter)
Join a server based on an invite code.
Definition network_coordinator.cpp:526
ClientNetworkCoordinatorSocketHandler::CloseStunHandler
void CloseStunHandler(std::string_view token, uint8_t family=AF_UNSPEC)
Close the STUN handler.
Definition network_coordinator.cpp:637
ClientNetworkCoordinatorSocketHandler::connecter
std::map< std::string, std::pair< std::string, TCPServerConnecter * >, std::less<> > connecter
Based on tokens, the current (invite-code, connecter) that are pending.
Definition network_coordinator.h:56
ClientNetworkCoordinatorSocketHandler::newgrf_lookup_table_cursor
uint32_t newgrf_lookup_table_cursor
Last received cursor for the GameInfoNewGRFLookupTable updates.
Definition network_coordinator.h:62
ClientNetworkCoordinatorSocketHandler::SendReceive
void SendReceive()
Check whether we received/can send some data from/to the Game Coordinator server and when that's the ...
Definition network_coordinator.cpp:732
ClientNetworkCoordinatorSocketHandler::IDLE_TIMEOUT
static constexpr std::chrono::seconds IDLE_TIMEOUT
The idle timeout; when to close the connection because it's idle.
Definition network_coordinator.h:79
ClientNetworkCoordinatorSocketHandler::next_update
std::chrono::steady_clock::time_point next_update
When to send the next update (if server and public).
Definition network_coordinator.h:55
ClientNetworkCoordinatorSocketHandler::connecting
bool connecting
Are we connecting to the Game Coordinator?
Definition network_coordinator.h:82
ClientNetworkCoordinatorSocketHandler::CloseAllConnections
void CloseAllConnections()
Close all pending connection tokens.
Definition network_coordinator.cpp:700
ClientNetworkCoordinatorSocketHandler::SendServerUpdate
void SendServerUpdate()
Send an update of our server status to the Game Coordinator.
Definition network_coordinator.cpp:488
ClientNetworkCoordinatorSocketHandler::connecter_pre
std::map< std::string, TCPServerConnecter *, std::less<> > connecter_pre
Based on invite codes, the current connecters that are pending.
Definition network_coordinator.h:57
ClientNetworkCoordinatorSocketHandler::Receive_GC_LISTING
bool Receive_GC_LISTING(Packet &p) override
Game Coordinator replies with a list of all public servers.
Definition network_coordinator.cpp:238
ClientNetworkCoordinatorSocketHandler::ConnectFailure
void ConnectFailure(std::string_view token, uint8_t tracking_number)
Callback from a Connecter to let the Game Coordinator know the connection failed.
Definition network_coordinator.cpp:557
ClientNetworkCoordinatorSocketHandler::CloseToken
void CloseToken(std::string_view token)
Close everything related to this connection token.
Definition network_coordinator.cpp:683
ClientNetworkCoordinatorSocketHandler::last_activity
std::chrono::steady_clock::time_point last_activity
The last time there was network activity.
Definition network_coordinator.h:81
ClientNetworkCoordinatorSocketHandler::StunResult
void StunResult(std::string_view token, uint8_t family, bool result)
Callback from the STUN connecter to inform the Game Coordinator about the result of the STUN.
Definition network_coordinator.cpp:621
ClientNetworkCoordinatorSocketHandler::Receive_GC_DIRECT_CONNECT
bool Receive_GC_DIRECT_CONNECT(Packet &p) override
Game Coordinator requests that the Client makes a direct connection to the indicated peer,...
Definition network_coordinator.cpp:300
ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECTING
bool Receive_GC_CONNECTING(Packet &p) override
Game Coordinator informs the Client under what token it will start the attempt to connect the Server ...
Definition network_coordinator.cpp:271
ClientNetworkCoordinatorSocketHandler::Receive_GC_TURN_CONNECT
bool Receive_GC_TURN_CONNECT(Packet &p) override
Game Coordinator requests that we make a connection to the indicated peer, which is a TURN server.
Definition network_coordinator.cpp:375
ClientNetworkCoordinatorSocketHandler::CloseConnection
NetworkRecvStatus CloseConnection(bool error=true) override
This will put this socket handler in a close state.
Definition network_coordinator.cpp:440
ClientNetworkCoordinatorSocketHandler::ConnectSuccess
void ConnectSuccess(std::string_view token, SOCKET sock, NetworkAddress &address)
Callback from a Connecter to let the Game Coordinator know the connection to the game server is estab...
Definition network_coordinator.cpp:580
ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECT_FAILED
bool Receive_GC_CONNECT_FAILED(Packet &p) override
Game Coordinator informs the Client that it failed to find a way to connect the Client to the Server.
Definition network_coordinator.cpp:291
ClientNetworkCoordinatorSocketHandler::Receive_GC_ERROR
bool Receive_GC_ERROR(Packet &p) override
Game Coordinator indicates there was an error.
Definition network_coordinator.cpp:127
ClientNetworkCoordinatorSocketHandler::stun_handlers
std::map< std::string, std::map< int, std::unique_ptr< ClientNetworkStunSocketHandler > >, std::less<> > stun_handlers
All pending STUN handlers, stored by token:family.
Definition network_coordinator.h:58
ClientNetworkCoordinatorSocketHandler::game_connecter
std::shared_ptr< TCPConnecter > game_connecter
Pending connecter to the game server.
Definition network_coordinator.h:60
ClientNetworkCoordinatorSocketHandler::GetListing
void GetListing()
Request a listing of all public servers.
Definition network_coordinator.cpp:505
ClientNetworkStunSocketHandler::Stun
static std::unique_ptr< ClientNetworkStunSocketHandler > Stun(std::string_view token, uint8_t family)
Send a STUN packet to the STUN server.
Definition network_stun.cpp:89
ClientNetworkTurnSocketHandler::Turn
static std::unique_ptr< ClientNetworkTurnSocketHandler > Turn(std::string_view token, uint8_t tracking_number, std::string_view ticket, std::string_view connection_string)
Prepare a TURN connection.
Definition network_turn.cpp:95
NetworkAddress
Wrapper for (un)resolved network addresses; there's no reason to transform a numeric IP to a string a...
Definition address.h:28
NetworkAddress::GetPeerAddress
static NetworkAddress GetPeerAddress(SOCKET sock)
Get the peer address of a socket as NetworkAddress.
Definition address.cpp:397
NetworkAddress::GetHostname
const std::string & GetHostname()
Get the hostname; in case it wasn't given the IPv4 dotted representation is given.
Definition address.cpp:24
NetworkCoordinatorConnecter
Connect to the Game Coordinator server.
Definition network_coordinator.cpp:103
NetworkCoordinatorConnecter::OnConnect
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
Definition network_coordinator.cpp:117
NetworkCoordinatorConnecter::OnFailure
void OnFailure() override
Callback for when the connection attempt failed.
Definition network_coordinator.cpp:111
NetworkCoordinatorConnecter::NetworkCoordinatorConnecter
NetworkCoordinatorConnecter(std::string_view connection_string)
Initiate the connecting.
Definition network_coordinator.cpp:109
NetworkCoordinatorSocketHandler::ReceivePackets
bool ReceivePackets()
Receive a packet at TCP level.
Definition tcp_coordinator.cpp:58
NetworkDirectConnecter
Connect to a game server by IP:port.
Definition network_coordinator.cpp:35
NetworkDirectConnecter::tracking_number
uint8_t tracking_number
Tracking number of this connection.
Definition network_coordinator.cpp:38
NetworkDirectConnecter::OnFailure
void OnFailure() override
Callback for when the connection attempt failed.
Definition network_coordinator.cpp:50
NetworkDirectConnecter::NetworkDirectConnecter
NetworkDirectConnecter(std::string_view hostname, uint16_t port, std::string &&token, uint8_t tracking_number)
Try to establish a direct (hostname:port based) connection.
Definition network_coordinator.cpp:48
NetworkDirectConnecter::OnConnect
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
Definition network_coordinator.cpp:55
NetworkDirectConnecter::token
std::string token
Token of this connection.
Definition network_coordinator.cpp:37
NetworkReuseStunConnecter
Connecter used after STUN exchange to connect from both sides to each other.
Definition network_coordinator.cpp:63
NetworkReuseStunConnecter::OnConnect
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
Definition network_coordinator.cpp:95
NetworkReuseStunConnecter::tracking_number
uint8_t tracking_number
Tracking number of this connection.
Definition network_coordinator.cpp:66
NetworkReuseStunConnecter::NetworkReuseStunConnecter
NetworkReuseStunConnecter(std::string_view hostname, uint16_t port, const NetworkAddress &bind_address, std::string &&token, uint8_t tracking_number, uint8_t family)
Try to establish a STUN-based connection.
Definition network_coordinator.cpp:79
NetworkReuseStunConnecter::OnFailure
void OnFailure() override
Callback for when the connection attempt failed.
Definition network_coordinator.cpp:87
NetworkReuseStunConnecter::family
uint8_t family
Family of this connection.
Definition network_coordinator.cpp:67
NetworkReuseStunConnecter::token
std::string token
Token of this connection.
Definition network_coordinator.cpp:65
NetworkSocketHandler::Reopen
void Reopen()
Reopen the socket so we can send/receive stuff again.
Definition core.h:79
NetworkTCPSocketHandler::CloseConnection
virtual NetworkRecvStatus CloseConnection(bool error=true)
This will put this socket handler in a close state.
Definition tcp.cpp:41
NetworkTCPSocketHandler::sock
SOCKET sock
The socket currently connected to.
Definition tcp.h:38
NetworkTCPSocketHandler::SendPacket
virtual void SendPacket(std::unique_ptr< Packet > &&packet)
This function puts the packet in the send-queue and it is send as soon as possible.
Definition tcp.cpp:58
NetworkTCPSocketHandler::SendPackets
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
Definition tcp.cpp:76
NetworkTCPSocketHandler::CloseSocket
void CloseSocket()
Close the actual socket of the connection.
Definition tcp.cpp:29
NetworkTCPSocketHandler::CanSendReceive
bool CanSendReceive()
Check whether this socket can send or receive something.
Definition tcp.cpp:194
ServerNetworkGameSocketHandler::GetName
static std::string_view GetName()
Get the name used by the listener.
Definition network_server.h:113
ServerNetworkGameSocketHandler::AcceptConnection
static void AcceptConnection(SOCKET s, const NetworkAddress &address)
Handle the accepting of a connection to the server.
Definition network.cpp:567
TCPConnecter
"Helper" class for creating TCP connections in a non-blocking manner
Definition tcp.h:74
TCPConnecter::bind_address
NetworkAddress bind_address
Address we're binding to, if any.
Definition tcp.h:104
TCPConnecter::connection_string
std::string connection_string
Current address we are connecting to (before resolving).
Definition tcp.h:103
TCPServerConnecter
Definition tcp.h:155
NetworkCoordinatorConnectionString
std::string_view NetworkCoordinatorConnectionString()
Get the connection string for the game coordinator from the environment variable OTTD_COORDINATOR_CS,...
Definition config.cpp:23
NETWORK_INVITE_CODE_SECRET_LENGTH
static const uint NETWORK_INVITE_CODE_SECRET_LENGTH
The maximum length of the invite code secret, in bytes including '\0'.
Definition config.h:70
TCP_MTU
static const size_t TCP_MTU
Number of bytes we can pack in a single TCP packet.
Definition config.h:45
NETWORK_COORDINATOR_SERVER_PORT
static const uint16_t NETWORK_COORDINATOR_SERVER_PORT
The default port of the Game Coordinator server (TCP)
Definition config.h:21
NETWORK_COORDINATOR_VERSION
static const uint8_t NETWORK_COORDINATOR_VERSION
What version of game-coordinator-protocol do we use?
Definition config.h:50
NETWORK_INVITE_CODE_LENGTH
static const uint NETWORK_INVITE_CODE_LENGTH
The maximum length of the invite code, in bytes including '\0'.
Definition config.h:69
NETWORK_HOSTNAME_PORT_LENGTH
static const uint NETWORK_HOSTNAME_PORT_LENGTH
The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port numb...
Definition config.h:55
NETWORK_HOSTNAME_LENGTH
static const uint NETWORK_HOSTNAME_LENGTH
The maximum length of the host name, in bytes including '\0'.
Definition config.h:54
NETWORK_TOKEN_LENGTH
static const uint NETWORK_TOKEN_LENGTH
The maximum length of a token, in bytes including '\0'.
Definition config.h:71
NETWORK_ERROR_DETAIL_LENGTH
static const uint NETWORK_ERROR_DETAIL_LENGTH
The maximum length of the error detail, in bytes including '\0'.
Definition config.h:68
NETWORK_GAME_INFO_VERSION
static const uint8_t NETWORK_GAME_INFO_VERSION
What version of game-info do we use?
Definition config.h:49
NetworkRecvStatus
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
Definition core.h:23
NETWORK_RECV_STATUS_OKAY
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
Definition core.h:24
Debug
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
WL_ERROR
@ WL_ERROR
Errors (eg. saving/loading failed)
Definition error.h:26
ShowErrorMessage
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
Definition error_gui.cpp:296
_frame_counter
uint32_t _frame_counter
The current frame.
Definition network.cpp:80
_network_dedicated
bool _network_dedicated
are we a dedicated server?
Definition network.cpp:70
_network_server
bool _network_server
network-server is active
Definition network.cpp:68
network.h
Basic functions/variables used all over the place.
_network_server_connection_type
ConnectionType _network_server_connection_type
What type of connection the Game Coordinator detected we are on.
Definition network_coordinator.cpp:31
_network_coordinator_client
ClientNetworkCoordinatorSocketHandler _network_coordinator_client
The connection to the Game Coordinator.
Definition network_coordinator.cpp:30
NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES
static const auto NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES
How many time between updates the server sends to the Game Coordinator.
Definition network_coordinator.cpp:29
_network_server_invite_code
std::string _network_server_invite_code
Our invite code as indicated by the Game Coordinator.
Definition network_coordinator.cpp:32
network_coordinator.h
Part of the network protocol handling Game Coordinator requests.
NetworkGameListAddItem
NetworkGame * NetworkGameListAddItem(std::string_view connection_string)
Add a new item to the linked gamelist.
Definition network_gamelist.cpp:30
NetworkGameListRemoveExpired
void NetworkGameListRemoveExpired()
Remove all servers that have not recently been updated.
Definition network_gamelist.cpp:68
_network_game_list_version
int _network_game_list_version
Current version of all items in the list.
Definition network_gamelist.cpp:22
network_gamelist.h
Handling of the list of games.
NGLS_ONLINE
@ NGLS_ONLINE
Server is online.
Definition network_gamelist.h:20
NGLS_OFFLINE
@ NGLS_OFFLINE
Server is offline (or cannot be queried).
Definition network_gamelist.h:19
UpdateNetworkGameWindow
void UpdateNetworkGameWindow()
Update the network new window because a new server is found on the network.
Definition network_gui.cpp:66
ShowNetworkAskRelay
void ShowNetworkAskRelay(std::string_view server_connection_string, std::string &&relay_connection_string, std::string &&token)
Show a modal confirmation window with "no" / "yes, once" / "yes, always" buttons.
Definition network_gui.cpp:2231
network_gui.h
GUIs related to networking.
NRWCD_HANDLED
@ NRWCD_HANDLED
Relay request is handled, either by user or by timeout.
Definition network_gui.h:43
network_internal.h
Variables and function used internally.
network_server.h
Server part of the network protocol.
network_stun.h
Part of the network protocol handling STUN requests.
ClearGRFConfigList
void ClearGRFConfigList(GRFConfigList &config)
Clear a GRF Config list, freeing all nodes.
Definition newgrf_config.cpp:324
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
GetEncodedString
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
ClientSettings::network
NetworkSettings network
settings related to the network
Definition settings_type.h:651
NetworkGame
Structure with information shown in the game list (GUI)
Definition network_gamelist.h:27
NetworkGame::version
int version
Used to see which servers are no longer available on the Game Coordinator and can be removed.
Definition network_gamelist.h:35
NetworkGame::info
NetworkGameInfo info
The game information of this server.
Definition network_gamelist.h:30
NetworkGame::status
NetworkGameStatus status
Stats of the server.
Definition network_gamelist.h:32
NetworkServerGameInfo::grfconfig
GRFConfigList grfconfig
List of NewGRF files used.
Definition network_game_info.h:98
NetworkSettings::server_invite_code_secret
std::string server_invite_code_secret
Secret to proof we got this invite code from the Game Coordinator.
Definition settings_type.h:348
NetworkSettings::server_game_type
ServerGameType server_game_type
Server type: local / public / invite-only.
Definition settings_type.h:346
NetworkSettings::use_relay_service
UseRelayService use_relay_service
Use relay service?
Definition settings_type.h:371
NetworkSettings::server_port
uint16_t server_port
port the server listens on
Definition settings_type.h:343
NetworkSettings::server_invite_code
std::string server_invite_code
Invite code to use when registering as server.
Definition settings_type.h:347
Packet
Internal entity of a packet.
Definition packet.h:43
Packet::Recv_uint16
uint16_t Recv_uint16()
Read a 16 bits integer from the packet.
Definition packet.cpp:332
Packet::Recv_uint32
uint32_t Recv_uint32()
Read a 32 bits integer from the packet.
Definition packet.cpp:347
Packet::Recv_string
std::string Recv_string(size_t length, StringValidationSettings settings=StringValidationSetting::ReplaceWithQuestionMark)
Reads characters (bytes) from the packet until it finds a '\0', or reaches a maximum of length charac...
Definition packet.cpp:425
Packet::Recv_uint8
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition packet.cpp:318
PACKET_COORDINATOR_SERCLI_CONNECT_FAILED
@ PACKET_COORDINATOR_SERCLI_CONNECT_FAILED
Client/server tells the Game Coordinator the current connection attempt failed.
Definition tcp_coordinator.h:37
PACKET_COORDINATOR_SERCLI_STUN_RESULT
@ PACKET_COORDINATOR_SERCLI_STUN_RESULT
Client/server informs the Game Coordinator of the result of the STUN request.
Definition tcp_coordinator.h:42
PACKET_COORDINATOR_CLIENT_LISTING
@ PACKET_COORDINATOR_CLIENT_LISTING
Client is requesting a listing of all public servers.
Definition tcp_coordinator.h:33
PACKET_COORDINATOR_SERVER_REGISTER
@ PACKET_COORDINATOR_SERVER_REGISTER
Server registration.
Definition tcp_coordinator.h:30
PACKET_COORDINATOR_CLIENT_CONNECT
@ PACKET_COORDINATOR_CLIENT_CONNECT
Client wants to connect to a server based on an invite code.
Definition tcp_coordinator.h:35
PACKET_COORDINATOR_CLIENT_CONNECTED
@ PACKET_COORDINATOR_CLIENT_CONNECTED
Client informs the Game Coordinator the connection with the server is established.
Definition tcp_coordinator.h:39
PACKET_COORDINATOR_SERVER_UPDATE
@ PACKET_COORDINATOR_SERVER_UPDATE
Server sends an set intervals an update of the server.
Definition tcp_coordinator.h:32
NetworkCoordinatorErrorType
NetworkCoordinatorErrorType
The type of error from the Game Coordinator.
Definition tcp_coordinator.h:63
NETWORK_COORDINATOR_ERROR_UNKNOWN
@ NETWORK_COORDINATOR_ERROR_UNKNOWN
There was an unknown error.
Definition tcp_coordinator.h:64
NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED
@ NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED
Your request for registration failed.
Definition tcp_coordinator.h:65
NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE
@ NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE
The invite code given is invalid.
Definition tcp_coordinator.h:66
NETWORK_COORDINATOR_ERROR_REUSE_OF_INVITE_CODE
@ NETWORK_COORDINATOR_ERROR_REUSE_OF_INVITE_CODE
The invite code is used by another (newer) server.
Definition tcp_coordinator.h:67
ConnectionType
ConnectionType
The type of connection the Game Coordinator can detect we have.
Definition tcp_coordinator.h:52
CONNECTION_TYPE_ISOLATED
@ CONNECTION_TYPE_ISOLATED
The Game Coordinator failed to find a way to connect to your server. Nobody will be able to join.
Definition tcp_coordinator.h:54
CONNECTION_TYPE_DIRECT
@ CONNECTION_TYPE_DIRECT
The Game Coordinator can directly connect to your server.
Definition tcp_coordinator.h:55
CONNECTION_TYPE_STUN
@ CONNECTION_TYPE_STUN
The Game Coordinator can connect to your server via a STUN request.
Definition tcp_coordinator.h:56
CONNECTION_TYPE_UNKNOWN
@ CONNECTION_TYPE_UNKNOWN
The Game Coordinator hasn't informed us yet what type of connection we have.
Definition tcp_coordinator.h:53
CONNECTION_TYPE_TURN
@ CONNECTION_TYPE_TURN
The Game Coordinator needs you to connect to a relay.
Definition tcp_coordinator.h:57
CloseWindowByClass
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition window.cpp:1207
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3179
WC_NETWORK_ASK_RELAY
@ WC_NETWORK_ASK_RELAY
Network ask relay window; Window numbers:
Definition window_type.h:502
WC_CLIENT_LIST
@ WC_CLIENT_LIST
Client list; Window numbers:
Definition window_type.h:489