|
OpenTTD Source
12.0-beta1
|
Go to the documentation of this file.
10 #include "../stdafx.h"
14 #include "../settings_type.h"
15 #include "../strings_func.h"
16 #include "../window_func.h"
17 #include "../window_type.h"
25 #include "table/strings.h"
27 #include "../safeguards.h"
150 connecter_pre_it->second->SetFailure();
163 Debug(net, 0,
"Invalid error type {} received from Game Coordinator",
error);
172 this->
next_update = std::chrono::steady_clock::now();
192 std::string connection_type;
200 default: connection_type =
"Unknown";
break;
203 std::string game_type;
205 case SERVER_GAME_TYPE_INVITE_ONLY: game_type =
"Invite only";
break;
206 case SERVER_GAME_TYPE_PUBLIC: game_type =
"Public";
break;
208 case SERVER_GAME_TYPE_LOCAL:
209 default: game_type =
"Unknown";
break;
212 Debug(net, 3,
"----------------------------------------");
213 Debug(net, 3,
"Your server is now registered with the Game Coordinator:");
214 Debug(net, 3,
" Game type: {}", game_type);
215 Debug(net, 3,
" Connection type: {}", connection_type);
217 Debug(net, 3,
"----------------------------------------");
235 for (; servers > 0; servers--) {
267 auto connecter_pre_it = this->
connecter_pre.find(invite_code);
274 this->
connecter[token] = connecter_pre_it->second;
325 auto family_it = stun_it->second.find(family);
326 if (family_it == stun_it->second.end())
return true;
338 family_it->second->CloseConnection(
false);
353 for (; newgrfs> 0; newgrfs--) {
386 this->StartTurnConnection(token);
390 this->StartTurnConnection(token);
396 void ClientNetworkCoordinatorSocketHandler::StartTurnConnection(std::string &token)
401 turn_it->second->Connect();
404 void ClientNetworkCoordinatorSocketHandler::Connect()
466 Debug(net, 6,
"Sending server update to Game Coordinator");
504 if (this->
connecter_pre.find(invite_code) != this->connecter_pre.end()) {
558 if (!ServerNetworkGameSocketHandler::ValidateClient(
sock, address))
return;
572 auto connecter_it = this->
connecter.find(token);
573 if (connecter_it != this->
connecter.end()) {
574 connecter_it->second->SetConnected(
sock);
610 if (family == AF_UNSPEC) {
611 for (
auto &[family, stun_handler] : stun_it->second) {
612 stun_handler->CloseConnection();
613 stun_handler->CloseSocket();
618 auto family_it = stun_it->second.find(family);
619 if (family_it == stun_it->second.end())
return;
621 family_it->second->CloseConnection();
622 family_it->second->CloseSocket();
624 stun_it->second.erase(family_it);
639 turn_it->second->CloseConnection();
640 turn_it->second->CloseSocket();
658 auto connecter_it = this->
connecter.find(token);
659 if (connecter_it != this->
connecter.end()) {
660 connecter_it->second->SetFailure();
677 for (
auto &[token, it] : this->
connecter) {
687 this->connecter.clear();
693 this->connecter_pre.clear();
704 if (this->
sock != INVALID_SOCKET) {
710 static int last_attempt_backoff = 1;
711 static bool first_reconnect =
true;
713 if (this->
sock == INVALID_SOCKET) {
714 static std::chrono::steady_clock::time_point last_attempt = {};
721 if (std::chrono::steady_clock::now() < last_attempt + std::chrono::seconds(1) * last_attempt_backoff)
return;
723 last_attempt = std::chrono::steady_clock::now();
725 if (last_attempt_backoff < 32) {
726 last_attempt_backoff *= 2;
733 if (first_reconnect) {
734 first_reconnect =
false;
738 Debug(net, 1,
"Connection with Game Coordinator lost; reconnecting...");
743 last_attempt_backoff = 1;
744 first_reconnect =
true;
764 for (
const auto &[family, stun_handler] : families) {
765 stun_handler->SendReceive();
770 for (
auto turn_it = this->
turn_handlers.begin(); turn_it != this->turn_handlers.end(); ) {
771 if (turn_it->second->connect_started && turn_it->second->connecter ==
nullptr && !turn_it->second->IsConnected()) {
778 for (
const auto &[token, turn_handler] : this->
turn_handlers) {
779 turn_handler->SendReceive();
void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names)
Serializes the NetworkGameInfo struct to the packet.
The game information that is sent from the server to the clients with extra information only required...
uint32 _frame_counter
The current frame.
void ConnectFailure(const std::string &token, uint8 tracking_number)
Callback from a Connecter to let the Game Coordinator know the connection failed.
@ CONNECTION_TYPE_ISOLATED
The Game Coordinator failed to find a way to connect to your server. Nobody will be able to join.
NetworkDirectConnecter(const std::string &hostname, uint16 port, const std::string &token, uint8 tracking_number)
Try to establish a direct (hostname:port based) connection.
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
std::string connection_string
Current address we are connecting to (before resolving).
static const uint16 NETWORK_COORDINATOR_SERVER_PORT
The default port of the Game Coordinator server (TCP)
void ClearGRFConfigList(GRFConfig **config)
Clear a GRF Config list, freeing all nodes.
ConnectionType _network_server_connection_type
What type of connection the Game Coordinator detected we are on.
NetworkCoordinatorErrorType
The type of error from the Game Coordinator.
static const uint NETWORK_INVITE_CODE_SECRET_LENGTH
The maximum length of the invite code secret, in bytes including '\0'.
uint16 server_port
port the server listens on
"Helper" class for creating TCP connections in a non-blocking manner
@ PACKET_COORDINATOR_CLIENT_CONNECTED
Client informs the Game Coordinator the connection with the server is established.
bool _network_server
network-server is active
const char * NetworkCoordinatorConnectionString()
Get the connection string for the game coordinator from the environment variable OTTD_COORDINATOR_CS,...
std::string server_invite_code_secret
Secret to proof we got this invite code from the Game Coordinator.
@ WC_CLIENT_LIST
Client list; Window numbers:
@ CONNECTION_TYPE_DIRECT
The Game Coordinator can directly connect to your server.
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.
void ConnectSuccess(const std::string &token, SOCKET sock, NetworkAddress &address)
Callback from a Connecter to let the Game Coordinator know the connection to the game server is estab...
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).
void Kill()
Kill this connecter.
SOCKET sock
The socket currently connected to.
static const char * GetName()
Get the name used by the listener.
std::map< std::string, TCPServerConnecter * > connecter
Based on tokens, the current connecters that are pending.
bool Receive_GC_ERROR(Packet *p) override
Game Coordinator indicates there was an error.
void OnFailure() override
Callback for when the connection attempt failed.
ClientSettings _settings_client
The current settings for this game.
void UpdateNetworkGameWindow()
Update the network new window because a new server is found on the network.
NetworkGameList * NetworkGameListAddItem(const std::string &connection_string)
Add a new item to the linked gamelist.
static const auto NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES
How many time between updates the server sends to the Game Coordinator.
static const uint NETWORK_TOKEN_LENGTH
The maximum length of a token, in bytes including '\0'.
UseRelayService use_relay_service
Use relay service?
void Send_uint8(uint8 data)
Package a 8 bits integer in the packet.
static NetworkAddress GetPeerAddress(SOCKET sock)
Get the peer address of a socket as NetworkAddress.
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=nullptr, uint textref_stack_size=0, const uint32 *textref_stack=nullptr)
Display an error message in a window.
void Send_uint32(uint32 data)
Package a 32 bits integer in the packet.
@ PACKET_COORDINATOR_CLIENT_LISTING
Client is requesting a listing of all public servers.
void CloseAllConnections()
Close all pending connection tokens.
std::string Recv_string(size_t length, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads characters (bytes) from the packet until it finds a '\0', or reaches a maximum of length charac...
bool Receive_GC_STUN_REQUEST(Packet *p) override
Game Coordinator requests the client/server to do a STUN request to the STUN server.
std::string token
Token of this connection.
static const uint NETWORK_ERROR_DETAIL_LENGTH
The maximum length of the error detail, in bytes including '\0'.
uint32 Recv_uint32()
Read a 32 bits integer from the packet.
uint8 tracking_number
Tracking number of this connection.
@ NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE
The invite code given is invalid.
void ConnectToServer(const std::string &invite_code, TCPServerConnecter *connecter)
Join a server based on an invite code.
void Reopen()
Reopen the socket so we can send/receive stuff again.
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.
void ShowNetworkAskRelay(const std::string &connection_string, const std::string &token)
Show a modal confirmation window with "no" / "yes, once" / "yes, always" buttons.
@ PACKET_COORDINATOR_SERCLI_STUN_RESULT
Client/server informs the Game Coordinator of the result of the STUN request.
std::string token
Token of this connection.
std::map< std::string, std::map< int, std::unique_ptr< ClientNetworkStunSocketHandler > > > stun_handlers
All pending STUN handlers, stored by token:family.
TCPConnecter * game_connecter
Pending connecter to the game server.
bool StrStartsWith(const std::string_view str, const std::string_view prefix)
Check whether the given string starts with the given prefix.
NetworkRecvStatus CloseConnection(bool error=true) override
This will put this socket handler in a close state.
@ PACKET_COORDINATOR_CLIENT_CONNECT
Client wants to connect to a server based on an invite code.
@ PACKET_COORDINATOR_SERVER_REGISTER
Server registration.
void Send_uint16(uint16 data)
Package a 16 bits integer in the packet.
virtual void SendPacket(Packet *packet)
This function puts the packet in the send-queue and it is send as soon as possible.
NetworkReuseStunConnecter(const std::string &hostname, uint16 port, const NetworkAddress &bind_address, std::string token, uint8 tracking_number, uint8 family)
Try to establish a STUN-based connection.
virtual NetworkRecvStatus CloseConnection(bool error=true)
This will put this socket handler in a close state.
int version
Used to see which servers are no longer available on the Game Coordinator and can be removed.
Connect to the Game Coordinator server.
void StunResult(const std::string &token, uint8 family, bool result)
Callback from the STUN connecter to inform the Game Coordinator about the result of the STUN.
static const uint16 TCP_MTU
Number of bytes we can pack in a single TCP packet.
void GetListing()
Request a listing of all public servers.
bool _network_dedicated
are we a dedicated server?
void Register()
Register our server to receive our invite code.
Internal entity of a packet.
uint32 newgrf_lookup_table_cursor
Last received cursor for the GameInfoNewGRFLookupTable updates.
static void AcceptConnection(SOCKET s, const NetworkAddress &address)
Handle the accepting of a connection to the server.
ConnectionType
The type of connection the Game Coordinator can detect we have.
@ NETWORK_COORDINATOR_ERROR_UNKNOWN
There was an unknown error.
void NetworkGameListRemoveExpired()
Remove all servers that have not recently been updated.
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...
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table)
Deserializes the NetworkGameInfo struct from the packet.
@ CONNECTION_TYPE_UNKNOWN
The Game Coordinator hasn't informed us yet what type of connection we have.
const NetworkServerGameInfo * GetCurrentNetworkServerGameInfo()
Get the NetworkServerGameInfo structure with the latest information of the server.
void Send_bool(bool data)
Package a boolean in the packet.
uint8 family
Family of this connection.
void OnFailure() override
Callback for when the connection attempt failed.
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
GameInfoNewGRFLookupTable newgrf_lookup_table
Table to look up NewGRFs in the GC_LISTING packets.
bool Receive_GC_LISTING(Packet *p) override
Game Coordinator replies with a list of all public servers.
ServerGameType server_game_type
Server type: local / public / invite-only.
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
bool Receive_GC_DIRECT_CONNECT(Packet *p) override
Game Coordinator requests that the Client makes a direct connection to the indicated peer,...
Wrapper for (un)resolved network addresses; there's no reason to transform a numeric IP to a string a...
std::map< std::string, TCPServerConnecter * > connecter_pre
Based on invite codes, the current connecters that are pending.
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...
bool CanSendReceive()
Check whether this socket can send or receive something.
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
void SendReceive()
Check whether we received/can send some data from/to the Game Coordinator server and when that's the ...
void CloseWindowByClass(WindowClass cls)
Close all windows of a given class.
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
std::chrono::steady_clock::time_point last_activity
The last time there was network activity.
Game Coordinator communication.
static const uint NETWORK_INVITE_CODE_LENGTH
The maximum length of the invite code, in bytes including '\0'.
Connecter used after STUN exchange to connect from both sides to each other.
ClientNetworkCoordinatorSocketHandler _network_coordinator_client
The connection to the Game Coordinator.
std::string server_invite_code
Invite code to use when registering as server.
const std::string & GetHostname()
Get the hostname; in case it wasn't given the IPv4 dotted representation is given.
@ WC_NETWORK_ASK_RELAY
Network ask relay window; Window numbers:
void SendServerUpdate()
Send an update of our server status to the Game Coordinator.
@ CONNECTION_TYPE_TURN
The Game Coordinator needs you to connect to a relay.
NetworkCoordinatorConnecter(const std::string &connection_string)
Initiate the connecting.
uint8 Recv_uint8()
Read a 8 bits integer from the packet.
std::chrono::steady_clock::time_point next_update
When to send the next update (if server and public).
@ WL_ERROR
Errors (eg. saving/loading failed)
static std::unique_ptr< ClientNetworkStunSocketHandler > Stun(const std::string &token, uint8 family)
Send a STUN packet to the STUN server.
void OnFailure() override
Callback for when the connection attempt failed.
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
void CheckGameCompatibility(NetworkGameInfo &ngi)
Check if an game entry is compatible with our client.
Structure with information shown in the game list (GUI)
void Send_string(const std::string_view data)
Sends a string over the network.
std::map< std::string, std::unique_ptr< ClientNetworkTurnSocketHandler > > turn_handlers
Pending TURN handler (if any), stored by token.
void DeserializeGRFIdentifierWithName(Packet *p, NamedGRFIdentifier *grf)
Deserializes the NamedGRFIdentifier (GRF ID, MD5 checksum and name) from the packet.
#define Debug(name, level, format_string,...)
Ouptut a line of debugging information.
NetworkSettings network
settings related to the network
@ CONNECTION_TYPE_STUN
The Game Coordinator can connect to your server via a STUN request.
Connect to a game server by IP:port.
static const uint NETWORK_HOSTNAME_LENGTH
The maximum length of the host name, in bytes including '\0'.
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
void CloseToken(const std::string &token)
Close everything related to this connection token.
static const byte NETWORK_COORDINATOR_VERSION
What version of game-coordinator-protocol do we use?
void CloseTurnHandler(const std::string &token)
Close the TURN handler.
bool Receive_GC_REGISTER_ACK(Packet *p) override
Game Coordinator acknowledges the registration.
static const byte NETWORK_GAME_INFO_VERSION
What version of game-info do we use?
bool ReceivePackets()
Receive a packet at TCP level.
NetworkGameInfo info
The game information of this server.
static std::unique_ptr< ClientNetworkTurnSocketHandler > Turn(const std::string &token, uint8 tracking_number, const std::string &ticket, const std::string &connection_string)
Prepare a TURN connection.
uint8 tracking_number
Tracking number of this connection.
@ PACKET_COORDINATOR_SERCLI_CONNECT_FAILED
Client/server tells the Game Coordinator the current connection attempt failed.
int _network_game_list_version
Current version of all items in the list.
std::string _network_server_invite_code
Our invite code as indicated by the Game Coordinator.
bool online
False if the server did not respond (default status)
GRFConfig * grfconfig
List of NewGRF files used.
NetworkAddress bind_address
Address we're binding to, if any.
void CloseSocket()
Close the actual socket of the connection.
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
@ PACKET_COORDINATOR_SERVER_UPDATE
Server sends an set intervals an update of the server.
@ NETWORK_COORDINATOR_ERROR_REGISTRATION_FAILED
Your request for registration failed.
uint16 Recv_uint16()
Read a 16 bits integer from the packet.
bool connecting
Are we connecting to the Game Coordinator?
static constexpr std::chrono::seconds IDLE_TIMEOUT
The idle timeout; when to close the connection because it's idle.
void CloseStunHandler(const std::string &token, uint8 family=AF_UNSPEC)
Close the STUN handler.
bool Receive_GC_CONNECTING(Packet *p) override
Game Coordinator informs the Client under what token it will start the attempt to connect the Server ...