mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-16 00:12:51 +00:00
c4b700f1b0
Currently it says "the server" which is a bit ambigious. Be more specific.
111 lines
5.5 KiB
C++
111 lines
5.5 KiB
C++
/*
|
|
* This file is part of OpenTTD.
|
|
* 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.
|
|
* 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.
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/** @file network_coordinator.h Part of the network protocol handling Game Coordinator requests. */
|
|
|
|
#ifndef NETWORK_COORDINATOR_H
|
|
#define NETWORK_COORDINATOR_H
|
|
|
|
#include "core/tcp_coordinator.h"
|
|
#include "network_stun.h"
|
|
#include "network_turn.h"
|
|
#include <map>
|
|
|
|
/**
|
|
* Game Coordinator communication.
|
|
* For more detail about what the Game Coordinator does, please see
|
|
* docs/game_coordinator.md.
|
|
*
|
|
* For servers:
|
|
* - Server sends SERVER_REGISTER.
|
|
* - Game Coordinator probes server to check if it can directly connect.
|
|
* - Game Coordinator sends GC_REGISTER_ACK with type of connection.
|
|
* - Server sends every 30 seconds SERVER_UPDATE.
|
|
*
|
|
* For clients (listing):
|
|
* - Client sends CLIENT_LISTING.
|
|
* - Game Coordinator returns the full list of public servers via GC_LISTING (multiple packets).
|
|
*
|
|
* For clients (connecting):
|
|
* - Client sends CLIENT_CONNECT.
|
|
* - Game Coordinator checks what type of connections the servers supports:
|
|
* 1) Direct connect?
|
|
* - Send the client a GC_CONNECT with the peer address.
|
|
* - a) Client connects, client sends CLIENT_CONNECTED to Game Coordinator.
|
|
* - b) Client connect fails, client sends CLIENT_CONNECT_FAILED to Game Coordinator.
|
|
* 2) STUN?
|
|
* - Game Coordinator sends GC_STUN_REQUEST to server/client (asking for both IPv4 and IPv6 STUN requests).
|
|
* - Game Coordinator collects what combination works and sends GC_STUN_CONNECT to server/client.
|
|
* - a) Server/client connect, client sends CLIENT_CONNECTED to Game Coordinator.
|
|
* - b) Server/client connect fails, both send SERCLI_CONNECT_FAILED to Game Coordinator.
|
|
* - Game Coordinator tries other combination if available.
|
|
* 3) TURN?
|
|
* - Game Coordinator sends GC_TURN_CONNECT to server/client.
|
|
* - a) Server/client connect, client sends CLIENT_CONNECTED to Game Coordinator.
|
|
* - b) Server/client connect fails, both send SERCLI_CONNECT_FAILED to Game Coordinator.
|
|
* - If all fails, Game Coordinator sends GC_CONNECT_FAILED to indicate no connection is possible.
|
|
*/
|
|
|
|
/** Class for handling the client side of the Game Coordinator connection. */
|
|
class ClientNetworkCoordinatorSocketHandler : public NetworkCoordinatorSocketHandler {
|
|
private:
|
|
std::chrono::steady_clock::time_point next_update; ///< When to send the next update (if server and public).
|
|
std::map<std::string, std::pair<std::string, TCPServerConnecter *>> connecter; ///< Based on tokens, the current (invite-code, connecter) that are pending.
|
|
std::map<std::string, TCPServerConnecter *> connecter_pre; ///< Based on invite codes, the current connecters that are pending.
|
|
std::map<std::string, std::map<int, std::unique_ptr<ClientNetworkStunSocketHandler>>> stun_handlers; ///< All pending STUN handlers, stored by token:family.
|
|
std::map<std::string, std::unique_ptr<ClientNetworkTurnSocketHandler>> turn_handlers; ///< Pending TURN handler (if any), stored by token.
|
|
TCPConnecter *game_connecter = nullptr; ///< Pending connecter to the game server.
|
|
|
|
uint32 newgrf_lookup_table_cursor = 0; ///< Last received cursor for the #GameInfoNewGRFLookupTable updates.
|
|
GameInfoNewGRFLookupTable newgrf_lookup_table; ///< Table to look up NewGRFs in the GC_LISTING packets.
|
|
|
|
protected:
|
|
bool Receive_GC_ERROR(Packet *p) override;
|
|
bool Receive_GC_REGISTER_ACK(Packet *p) override;
|
|
bool Receive_GC_LISTING(Packet *p) override;
|
|
bool Receive_GC_CONNECTING(Packet *p) override;
|
|
bool Receive_GC_CONNECT_FAILED(Packet *p) override;
|
|
bool Receive_GC_DIRECT_CONNECT(Packet *p) override;
|
|
bool Receive_GC_STUN_REQUEST(Packet *p) override;
|
|
bool Receive_GC_STUN_CONNECT(Packet *p) override;
|
|
bool Receive_GC_NEWGRF_LOOKUP(Packet *p) override;
|
|
bool Receive_GC_TURN_CONNECT(Packet *p) override;
|
|
|
|
public:
|
|
/** The idle timeout; when to close the connection because it's idle. */
|
|
static constexpr std::chrono::seconds IDLE_TIMEOUT = std::chrono::seconds(60);
|
|
|
|
std::chrono::steady_clock::time_point last_activity; ///< The last time there was network activity.
|
|
bool connecting; ///< Are we connecting to the Game Coordinator?
|
|
|
|
ClientNetworkCoordinatorSocketHandler() : connecting(false) {}
|
|
|
|
NetworkRecvStatus CloseConnection(bool error = true) override;
|
|
void SendReceive();
|
|
|
|
void ConnectFailure(const std::string &token, uint8 tracking_number);
|
|
void ConnectSuccess(const std::string &token, SOCKET sock, NetworkAddress &address);
|
|
void StunResult(const std::string &token, uint8 family, bool result);
|
|
|
|
void Connect();
|
|
void CloseToken(const std::string &token);
|
|
void CloseAllConnections();
|
|
void CloseStunHandler(const std::string &token, uint8 family = AF_UNSPEC);
|
|
void CloseTurnHandler(const std::string &token);
|
|
|
|
void Register();
|
|
void SendServerUpdate();
|
|
void GetListing();
|
|
|
|
void ConnectToServer(const std::string &invite_code, TCPServerConnecter *connecter);
|
|
void StartTurnConnection(std::string &token);
|
|
};
|
|
|
|
extern ClientNetworkCoordinatorSocketHandler _network_coordinator_client;
|
|
|
|
#endif /* NETWORK_COORDINATOR_H */
|