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