1 #ifndef _ClientNetworking_h_
2 #define _ClientNetworking_h_
3 
4 #include <boost/optional/optional_fwd.hpp>
5 
6 #include <string>
7 #include <vector>
8 #include <memory>
9 #include <chrono>
10 
11 #include <memory>
12 
13 class Message;
14 
15 namespace Networking {
16     class AuthRoles;
17 
18     enum RoleType : size_t;
19 }
20 
21 /** Encapsulates the networking facilities of the client.  The client must
22     execute its networking code in a separate thread from its main processing
23     thread, for UI and networking responsiveness.
24 
25     Because of this, ClientNetworking operates in two threads: the main
26     thread, in which the UI processing operates; the networking thread, which
27     is created and terminates when the client is connected to and disconnected
28     from the server, respectively.  The entire public interface is safe to
29     call from the main thread at all times.  Note that the main thread must
30     periodically request the next incoming message; the arrival of incoming
31     messages is never explicitly signalled to the main thread.  The same
32     applies to unintentional disconnects from the server.  The client must
33     periodically check IsConnected().
34 
35     The ClientNetworking has two modes of operation.  First, it can discover
36     FreeOrion servers on the local network; this is a blocking operation with
37     a timeout.  Second, it can send an asynchronous message to the server
38     (when connected); this is a non-blocking operation.*/
39 class ClientNetworking : public std::enable_shared_from_this<ClientNetworking> {
40 public:
41     /** The type of list returned by a call to DiscoverLANServers(). */
42     using ServerNames =  std::vector<std::string>;
43 
44     /** \name Structors */ //@{
45     ClientNetworking();
46     ~ClientNetworking();
47     //@}
48 
49     /** \name Accessors */ //@{
50     /** Returns true iff the client is full duplex connected to the server. */
51     bool IsConnected() const;
52 
53     /** Returns true iff the client is connected to receive from the server. */
54     bool IsRxConnected() const;
55 
56     /** Returns true iff the client is connected to send to the server. */
57     bool IsTxConnected() const;
58 
59     /** Returns the ID of the player on this client. */
60     int PlayerID() const;
61 
62     /** Returns the ID of the host player, or INVALID_PLAYER_ID if there is no host player. */
63     int HostPlayerID() const;
64 
65     /** Returns whether the indicated player ID is the host. */
66     bool PlayerIsHost(int player_id) const;
67 
68     /** Checks if the client has some authorization \a role. */
69     bool HasAuthRole(Networking::RoleType role) const;
70 
71     /** Returns address of multiplayer server entered by player. */
72     const std::string& Destination() const;
73     //@}
74 
75     /** \name Mutators */ //@{
76     /** Returns a list of the addresses and names of all servers on the Local
77         Area Network. */
78     ServerNames DiscoverLANServerNames();
79 
80     /** Connects to the server at \a ip_address.  On failure, repeated
81         attempts will be made until \a timeout seconds has elapsed. */
82     bool ConnectToServer(const std::string& ip_address,
83                          const std::chrono::milliseconds& timeout = std::chrono::seconds(10));
84 
85     /** Connects to the server on the client's host.  On failure, repeated
86         attempts will be made until \a timeout seconds has elapsed. */
87     bool ConnectToLocalHostServer(
88         const std::chrono::milliseconds& timeout = std::chrono::seconds(10));
89 
90     /** Return true if the server can be connected to within \p timeout seconds. */
91     bool PingServer(
92         const std::string& ip_address,
93         const std::chrono::milliseconds& timeout = std::chrono::seconds(10));
94 
95     /** Return true if the local server can be connected to within \p timeout seconds. */
96     bool PingLocalHostServer(
97         const std::chrono::milliseconds& timeout = std::chrono::seconds(10));
98 
99     /** Sends \a message to the server.  This function actually just enqueues
100         the message for sending and returns immediately. */
101     void SendMessage(const Message& message);
102 
103     /** Return the next incoming message from the server if available or boost::none.
104         Remove the message from the incoming message queue. */
105     boost::optional<Message> GetMessage();
106 
107     /** Disconnects the client from the server. First tries to send any pending transmit messages. */
108     void DisconnectFromServer();
109 
110     /** Sets player ID for this client. */
111     void SetPlayerID(int player_id);
112 
113     /** Sets Host player ID. */
114     void SetHostPlayerID(int host_player_id);
115 
116     /** Access to client's authorization roles */
117     Networking::AuthRoles& AuthorizationRoles();
118     //@}
119 
120 private:
121     class Impl;
122     std::unique_ptr<Impl> const m_impl;
123 };
124 
125 #endif // _ClientNetworking_h_
126