1 //
2 //  SuperTuxKart - a fun racing game with go-kart
3 //  Copyright (C) 2015 Joerg Henrichs
4 //
5 //  This program is free software; you can redistribute it and/or
6 //  modify it under the terms of the GNU General Public License
7 //  as published by the Free Software Foundation; either version 3
8 //  of the License, or (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 /*! \file network_config.hpp
20  *  \brief Defines network configuration for server and client.
21  */
22 #ifndef HEADER_NETWORK_CONFIG
23 #define HEADER_NETWORK_CONFIG
24 
25 #include "race/race_manager.hpp"
26 #include "utils/stk_process.hpp"
27 #include "utils/no_copy.hpp"
28 
29 #include "irrString.h"
30 #include <array>
31 #include <atomic>
32 #include <cstring>
33 #include <memory>
34 #include <set>
35 #include <tuple>
36 #include <vector>
37 #include <utility>
38 
39 namespace Online
40 {
41     class XMLRequest;
42 }
43 
44 namespace GUIEngine
45 {
46     class Screen;
47 }
48 
49 class InputDevice;
50 class PlayerProfile;
51 
52 class NetworkConfig : public NoCopy
53 {
54 public:
55     enum IPType : int
56     {
57         IP_NONE, IP_V4, IP_V6, IP_V6_NAT64, IP_DUAL_STACK
58     };
59 private:
60     /** The singleton instance. */
61     static NetworkConfig *m_network_config[PT_COUNT];
62 
63     static bool m_system_ipv4;
64 
65     static bool m_system_ipv6;
66 
67     enum NetworkType : int
68     {
69         NETWORK_NONE, NETWORK_WAN, NETWORK_LAN
70     };
71 
72     std::atomic<IPType> m_ip_type;
73 
74     /** Keeps the type of network connection: none (yet), LAN or WAN. */
75     std::atomic<NetworkType> m_network_type;
76 
77     /** If set it allows clients to connect directly to this server without
78      *  using the stk server in between. It requires obviously that this
79      *  server is accessible (through the firewall) from the outside. */
80     bool m_is_public_server;
81 
82     /** True if this host is a server, false otherwise. */
83     std::atomic_bool m_is_server;
84 
85     /** True if a client should connect to the first server it finds and
86      *  immediately start a race. */
87     bool m_auto_connect;
88 
89     bool m_done_adding_network_players;
90 
91     /** True if this STK instance is an AI instance which is used for server
92      *  AI. (usually used together with ai-handling in server config) */
93     bool m_network_ai_instance;
94 
95     /** When live join is disabled addon kart will use their real hitbox */
96     bool m_tux_hitbox_addon;
97 
98     /** No. of fixed AI in all-in-one graphical client server, the player
99      *  connecting with 127.* or ::1/128 will be in charged of controlling the
100      *  AI. */
101     unsigned m_num_fixed_ai;
102 
103     /** The LAN port on which a client is waiting for a server connection. */
104     uint16_t m_client_port;
105 
106     /** Used by wan server. */
107     uint32_t m_cur_user_id;
108     std::string m_cur_user_token;
109 
110     /** Used by client server to determine if the child server is created. */
111     std::string m_server_id_file;
112 
113     std::vector<std::tuple<InputDevice*, PlayerProfile*, HandicapLevel> > m_network_players;
114 
115     NetworkConfig();
116 
117     uint32_t m_joined_server_version;
118 
119     /** Set by client or server which is required to be the same. */
120     int m_state_frequency;
121 
122     /** List of server capabilities set when joining it, to determine features
123      *  available in same version. */
124     std::set<std::string> m_server_capabilities;
125 
126     /** For IPv6 only network we try to detect the NAT64 prefix so we can
127      *  use it to connect to ipv4 only servers. STK assumes that for all ipv4
128      *  addresses they use the same prefix for each initIPTest. */
129     std::string m_nat64_prefix;
130     std::array<uint32_t, 8> m_nat64_prefix_data;
131     // ------------------------------------------------------------------------
132     static void fillStunList(std::vector<std::pair<std::string, int> >* l,
133                              const std::string& dns);
134 
135 public:
136     static void initSystemIP();
137     // ------------------------------------------------------------------------
138     /** Singleton get, which creates this object if necessary. */
get()139     static NetworkConfig *get()
140     {
141         ProcessType type = STKProcess::getType();
142         if (!m_network_config[type])
143             m_network_config[type] = new NetworkConfig();
144         return m_network_config[type];
145     }   // get
146     // ------------------------------------------------------------------------
getByType(ProcessType type)147     static NetworkConfig* getByType(ProcessType type)
148     {
149         return m_network_config[type];
150     }   // get
151     // ------------------------------------------------------------------------
destroy()152     static void destroy()
153     {
154         ProcessType type = STKProcess::getType();
155         delete m_network_config[type];   // It's ok to delete NULL
156         m_network_config[type] = NULL;
157     }   // destroy
158     // ------------------------------------------------------------------------
clear()159     static void clear()
160     {
161         memset(m_network_config, 0, sizeof(m_network_config));
162     }   // clear
163     // ------------------------------------------------------------------------
164     /** Sets if this instance is a server or client. */
setIsServer(bool b)165     void setIsServer(bool b)
166     {
167         m_is_server = b;
168     }   // setIsServer
169     // ------------------------------------------------------------------------
170     /** Sets the port on which a client listens for server connection. */
setClientPort(uint16_t port)171     void setClientPort(uint16_t port) { m_client_port = port; }
172     // ------------------------------------------------------------------------
173     /** Returns the port on which a client listens for server connections. */
getClientPort() const174     uint16_t getClientPort() const { return m_client_port; }
175     // ------------------------------------------------------------------------
176     /** Sets that this server can be contacted directly. */
setIsPublicServer()177     void setIsPublicServer() { m_is_public_server = true; }
178     // ------------------------------------------------------------------------
179     /** Returns if connections directly to the server are to be accepted. */
isPublicServer() const180     bool isPublicServer() const { return m_is_public_server; }
181     // ------------------------------------------------------------------------
182     /** Return if a network setting is happening. A network setting is active
183      *  if a host (server or client) exists. */
isNetworking() const184     bool isNetworking() const { return m_network_type!=NETWORK_NONE; }
185     // ------------------------------------------------------------------------
186     /** Return true if it's a networked game with a LAN server. */
isLAN() const187     bool isLAN() const { return m_network_type == NETWORK_LAN; }
188     // ------------------------------------------------------------------------
189     /** Return true if it's a networked game but with a WAN server. */
isWAN() const190     bool isWAN() const { return m_network_type == NETWORK_WAN; }
191     // ------------------------------------------------------------------------
192     /** Set that this is a LAN networked game. */
setIsLAN()193     void setIsLAN() { m_network_type = NETWORK_LAN; }
194     // ------------------------------------------------------------------------
195     /** Set that this is a WAN networked game. */
setIsWAN()196     void setIsWAN() { m_network_type = NETWORK_WAN; }
197     // ------------------------------------------------------------------------
198     void unsetNetworking();
199     // ------------------------------------------------------------------------
200     std::vector<std::tuple<InputDevice*, PlayerProfile*, HandicapLevel> >&
getNetworkPlayers()201                         getNetworkPlayers()       { return m_network_players; }
202     // ------------------------------------------------------------------------
isAddingNetworkPlayers() const203     bool isAddingNetworkPlayers() const
204                                      { return !m_done_adding_network_players; }
205     // ------------------------------------------------------------------------
doneAddingNetworkPlayers()206     void doneAddingNetworkPlayers()   { m_done_adding_network_players = true; }
207     // ------------------------------------------------------------------------
addNetworkPlayer(InputDevice * device,PlayerProfile * profile,HandicapLevel h)208     bool addNetworkPlayer(InputDevice* device, PlayerProfile* profile,
209                           HandicapLevel h)
210     {
211         for (auto& p : m_network_players)
212         {
213             if (std::get<0>(p) == device && !m_network_ai_instance)
214                 return false;
215             if (std::get<1>(p) == profile)
216                 return false;
217         }
218         m_network_players.emplace_back(device, profile, h);
219         return true;
220     }
221     // ------------------------------------------------------------------------
playerExists(PlayerProfile * profile) const222     bool playerExists(PlayerProfile* profile) const
223     {
224         for (auto& p : m_network_players)
225         {
226             if (std::get<1>(p) == profile)
227                 return true;
228         }
229         return false;
230     }
231     // ------------------------------------------------------------------------
cleanNetworkPlayers()232     void cleanNetworkPlayers()
233     {
234         m_network_players.clear();
235         m_done_adding_network_players = false;
236     }
237     // ------------------------------------------------------------------------
238     /** Returns if this instance is a server. */
isServer() const239     bool isServer() const { return m_is_server;  }
240     // ------------------------------------------------------------------------
241     /** Returns if this instance is a client. */
isClient() const242     bool isClient() const { return !m_is_server; }
243     // ------------------------------------------------------------------------
244     /** Sets if a client should immediately connect to the first server. */
setAutoConnect(bool b)245     void setAutoConnect(bool b) { m_auto_connect = b; }
246     // ------------------------------------------------------------------------
247     /** Returns if an immediate connection to the first server was
248      *  requested. */
isAutoConnect() const249     bool isAutoConnect() const { return m_auto_connect; }
250     // ------------------------------------------------------------------------
setNetworkAIInstance(bool b)251     void setNetworkAIInstance(bool b) { m_network_ai_instance = b; }
252     // ------------------------------------------------------------------------
isNetworkAIInstance() const253     bool isNetworkAIInstance() const { return m_network_ai_instance; }
254     // ------------------------------------------------------------------------
setCurrentUserId(uint32_t id)255     void setCurrentUserId(uint32_t id) { m_cur_user_id = id ; }
256     // ------------------------------------------------------------------------
setCurrentUserToken(const std::string & t)257     void setCurrentUserToken(const std::string& t) { m_cur_user_token = t; }
258     // ------------------------------------------------------------------------
getCurrentUserId() const259     uint32_t getCurrentUserId() const { return m_cur_user_id; }
260     // ------------------------------------------------------------------------
getCurrentUserToken() const261     const std::string& getCurrentUserToken() const { return m_cur_user_token; }
262     // ------------------------------------------------------------------------
263     void setUserDetails(std::shared_ptr<Online::XMLRequest> r,
264                         const std::string& name);
265     // ------------------------------------------------------------------------
266     void setServerDetails(std::shared_ptr<Online::XMLRequest> r,
267                           const std::string& name);
268     // ------------------------------------------------------------------------
setServerIdFile(const std::string & id)269     void setServerIdFile(const std::string& id) { m_server_id_file = id; }
270     // ------------------------------------------------------------------------
getServerIdFile() const271     const std::string& getServerIdFile() const { return m_server_id_file; }
272     // ------------------------------------------------------------------------
273     std::vector<GUIEngine::Screen*> getResetScreens(bool lobby = false) const;
274     // ------------------------------------------------------------------------
setJoinedServerVersion(uint32_t v)275     void setJoinedServerVersion(uint32_t v)    { m_joined_server_version = v; }
276     // ------------------------------------------------------------------------
getJoinedServerVersion() const277     uint32_t getJoinedServerVersion() const { return m_joined_server_version; }
278     // ------------------------------------------------------------------------
279     void clearActivePlayersForClient() const;
280     // ------------------------------------------------------------------------
setStateFrequency(int frequency)281     void setStateFrequency(int frequency)    { m_state_frequency = frequency; }
282     // ------------------------------------------------------------------------
getStateFrequency() const283     int getStateFrequency() const                 { return m_state_frequency; }
284     // ------------------------------------------------------------------------
285     bool roundValuesNow() const;
286     // ------------------------------------------------------------------------
setServerCapabilities(std::set<std::string> & caps)287     void setServerCapabilities(std::set<std::string>& caps)
288                                    { m_server_capabilities = std::move(caps); }
289     // ------------------------------------------------------------------------
clearServerCapabilities()290     void clearServerCapabilities()           { m_server_capabilities.clear(); }
291     // ------------------------------------------------------------------------
getServerCapabilities() const292     const std::set<std::string>& getServerCapabilities() const
293                                               { return m_server_capabilities; }
294     // ------------------------------------------------------------------------
295     void detectIPType();
296     // ------------------------------------------------------------------------
getIPType() const297     IPType getIPType() const                       { return m_ip_type.load(); }
298     // ------------------------------------------------------------------------
setIPType(IPType ip_type)299     void setIPType(IPType ip_type)                { m_ip_type.store(ip_type); }
300     // ------------------------------------------------------------------------
getNAT64Prefix() const301     const std::string& getNAT64Prefix() const        { return m_nat64_prefix; }
302     // ------------------------------------------------------------------------
getNAT64PrefixData() const303     const std::array<uint32_t, 8>& getNAT64PrefixData() const
304                                                 { return m_nat64_prefix_data; }
305     // ------------------------------------------------------------------------
306     void initClientPort();
307     // ------------------------------------------------------------------------
setNumFixedAI(unsigned num)308     void setNumFixedAI(unsigned num)                  { m_num_fixed_ai = num; }
309     // ------------------------------------------------------------------------
getNumFixedAI() const310     unsigned getNumFixedAI() const                   { return m_num_fixed_ai; }
311     // ------------------------------------------------------------------------
312     static const std::vector<std::pair<std::string, int> >&
313                                                         getStunList(bool ipv4);
314     // ------------------------------------------------------------------------
setTuxHitboxAddon(bool val)315     void setTuxHitboxAddon(bool val)              { m_tux_hitbox_addon = val; }
316     // ------------------------------------------------------------------------
useTuxHitboxAddon() const317     bool useTuxHitboxAddon() const               { return m_tux_hitbox_addon; }
318 };   // class NetworkConfig
319 
320 #endif // HEADER_NETWORK_CONFIG
321