1 // 2 // SuperTuxKart - a fun racing game with go-kart 3 // Copyright (C) 2013-2015 SuperTuxKart-Team 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 stk_host.hpp 20 * \brief Defines an interface to use network low-level functions easily. 21 */ 22 #ifndef STK_HOST_HPP 23 #define STK_HOST_HPP 24 25 #include "utils/stk_process.hpp" 26 #include "utils/synchronised.hpp" 27 #include "utils/time.hpp" 28 29 #include "irrString.h" 30 31 // enet.h includes win32.h, which without lean_and_mean includes 32 // winspool.h, which defines MAX_PRIORITY as a macro, which then 33 // results in request_manager.hpp not being compilable. 34 #define WIN32_LEAN_AND_MEAN 35 #include <enet/enet.h> 36 37 #include <atomic> 38 #include <cassert> 39 #include <cstring> 40 #include <list> 41 #include <functional> 42 #include <map> 43 #include <memory> 44 #include <mutex> 45 #include <set> 46 #include <thread> 47 #include <tuple> 48 #include <vector> 49 50 class BareNetworkString; 51 class GameSetup; 52 class LobbyProtocol; 53 class Network; 54 class NetworkPlayerProfile; 55 class NetworkString; 56 class NetworkTimerSynchronizer; 57 class Server; 58 class ServerLobby; 59 class ChildLoop; 60 class SocketAddress; 61 class STKPeer; 62 63 using namespace irr; 64 65 enum ENetCommandType : unsigned int 66 { 67 ECT_SEND_PACKET = 0, 68 ECT_DISCONNECT = 1, 69 ECT_RESET = 2 70 }; 71 72 class STKHost 73 { 74 private: 75 /** Singleton pointer to the instance. */ 76 static STKHost* m_stk_host[PT_COUNT]; 77 78 /** Separate process of server instance. */ 79 ChildLoop* m_client_loop; 80 81 std::thread m_client_loop_thread; 82 83 /** ENet host interfacing sockets. */ 84 Network* m_network; 85 86 /** Network console thread */ 87 std::thread m_network_console; 88 89 /** Make sure the removing or adding a peer is thread-safe. */ 90 mutable std::mutex m_peers_mutex; 91 92 /** Let (atm enet_peer_send and enet_peer_disconnect) run in the listening 93 * thread. */ 94 std::vector<std::tuple</*peer receive*/ENetPeer*, 95 /*packet to send*/ENetPacket*, /*integer data*/uint32_t, 96 ENetCommandType, ENetAddress> > m_enet_cmd; 97 98 /** Protect \ref m_enet_cmd from multiple threads usage. */ 99 std::mutex m_enet_cmd_mutex; 100 101 /** The list of peers connected to this instance. */ 102 std::map<ENetPeer*, std::shared_ptr<STKPeer> > m_peers; 103 104 /** Next unique host id. It is increased whenever a new peer is added (see 105 * getPeer()), but not decreased whena host (=peer) disconnects. This 106 * results in a unique host id for each host, even when a host should 107 * disconnect and then reconnect. */ 108 uint32_t m_next_unique_host_id = 0; 109 110 /** Host id of this host. */ 111 uint32_t m_host_id = 0; 112 113 /** Id of thread listening to enet events. */ 114 std::thread m_listening_thread; 115 116 /** Flag which is set from the protocol manager thread which 117 * triggers a shutdown of the STKHost (and the Protocolmanager). */ 118 std::atomic_bool m_shutdown; 119 120 /** True if this local host is authorised to control a server. */ 121 std::atomic_bool m_authorised; 122 123 /** Use as a timeout to waiting a disconnect event when exiting. */ 124 std::atomic<uint64_t> m_exit_timeout; 125 126 /** An error message, which is set by a protocol to be displayed 127 * in the GUI. */ 128 irr::core::stringw m_error_message; 129 130 /** The public address found by stun (if WAN is used). */ 131 std::unique_ptr<SocketAddress> m_public_address; 132 133 /** The public IPv6 address found by stun (if WAN is used). */ 134 std::string m_public_ipv6_address; 135 136 /** The public IPv4 address stun server used. */ 137 std::unique_ptr<SocketAddress> m_stun_ipv4; 138 139 /** The public IPv6 address stun server used. */ 140 std::unique_ptr<SocketAddress> m_stun_ipv6; 141 142 Synchronised<std::map<uint32_t, uint32_t> > m_peer_pings; 143 144 std::atomic<uint32_t> m_client_ping; 145 146 std::atomic<uint32_t> m_upload_speed; 147 148 std::atomic<uint32_t> m_download_speed; 149 150 std::atomic<uint32_t> m_players_in_game; 151 152 std::atomic<uint32_t> m_players_waiting; 153 154 std::atomic<uint32_t> m_total_players; 155 156 std::atomic<int64_t> m_network_timer; 157 158 std::unique_ptr<NetworkTimerSynchronizer> m_nts; 159 160 // ------------------------------------------------------------------------ 161 STKHost(bool server); 162 // ------------------------------------------------------------------------ 163 ~STKHost(); 164 // ------------------------------------------------------------------------ 165 void init(); 166 // ------------------------------------------------------------------------ 167 void handleDirectSocketRequest(Network* direct_socket, 168 std::shared_ptr<ServerLobby> sl, 169 std::map<std::string, uint64_t>& ctp); 170 // ------------------------------------------------------------------------ 171 void mainLoop(ProcessType pt); 172 // ------------------------------------------------------------------------ 173 void getIPFromStun(int socket, const std::string& stun_address, 174 short family, SocketAddress* result); 175 public: 176 /** If a network console should be started. */ 177 static bool m_enable_console; 178 179 /** Creates the STKHost. It takes all confifguration parameters from 180 * NetworkConfig. This STKHost can either be a client or a server. 181 */ 182 static std::shared_ptr<LobbyProtocol> create(ChildLoop* cl = NULL); 183 // ------------------------------------------------------------------------ 184 /** Returns the instance of STKHost. */ get()185 static STKHost *get() 186 { 187 ProcessType pt = STKProcess::getType(); 188 assert(m_stk_host[pt] != NULL); 189 return m_stk_host[pt]; 190 } // get 191 // ------------------------------------------------------------------------ getByType(ProcessType pt)192 static STKHost *getByType(ProcessType pt) 193 { 194 assert(m_stk_host[pt] != NULL); 195 return m_stk_host[pt]; 196 } // get 197 // ------------------------------------------------------------------------ destroy()198 static void destroy() 199 { 200 ProcessType pt = STKProcess::getType(); 201 assert(m_stk_host[pt] != NULL); 202 delete m_stk_host[pt]; 203 m_stk_host[pt] = NULL; 204 } // destroy 205 // ------------------------------------------------------------------------ 206 /** Checks if the STKHost has been created. */ existHost()207 static bool existHost() 208 { return m_stk_host[STKProcess::getType()] != NULL; } 209 // ------------------------------------------------------------------------ clear()210 static void clear() { memset(m_stk_host, 0, sizeof(m_stk_host)); } 211 // ------------------------------------------------------------------------ getPublicAddress() const212 const SocketAddress& getPublicAddress() const 213 { return *m_public_address.get(); } 214 // ------------------------------------------------------------------------ getPublicIPv6Address() const215 const std::string& getPublicIPv6Address() const 216 { return m_public_ipv6_address; } 217 // ------------------------------------------------------------------------ 218 std::string getValidPublicAddress() const; 219 // ------------------------------------------------------------------------ getStunIPv4Address() const220 const SocketAddress* getStunIPv4Address() const 221 { return m_stun_ipv4.get(); } 222 // ------------------------------------------------------------------------ getStunIPv6Address() const223 const SocketAddress* getStunIPv6Address() const 224 { return m_stun_ipv6.get(); } 225 // ------------------------------------------------------------------------ 226 uint16_t getPrivatePort() const; 227 // ------------------------------------------------------------------------ 228 void setPublicAddress(short family); 229 // ------------------------------------------------------------------------ 230 void disconnectAllPeers(bool timeout_waiting = false); 231 //------------------------------------------------------------------------- 232 /** Requests that the network infrastructure is to be shut down. This 233 * function is called from a thread, but the actual shutdown needs to be 234 * done from the main thread to avoid race conditions (e.g. 235 * ProtocolManager might still access data structures when the main thread 236 * tests if STKHost exist (which it does, but ProtocolManager might be 237 * shut down already. 238 */ requestShutdown()239 void requestShutdown() 240 { 241 m_shutdown.store(true); 242 } // requestExit 243 //------------------------------------------------------------------------- 244 void shutdown(); 245 //------------------------------------------------------------------------- 246 void sendPacketToAllPeersInServer(NetworkString *data, 247 bool reliable = true); 248 // ------------------------------------------------------------------------ 249 void sendPacketToAllPeers(NetworkString *data, bool reliable = true); 250 // ------------------------------------------------------------------------ 251 void sendPacketToAllPeersWith(std::function<bool(STKPeer*)> predicate, 252 NetworkString* data, bool reliable = true); 253 // ------------------------------------------------------------------------ 254 /** Returns true if this client instance is allowed to control the server. 255 * It will auto transfer ownership if previous server owner disconnected. 256 */ isAuthorisedToControl() const257 bool isAuthorisedToControl() const { return m_authorised.load(); } 258 // ------------------------------------------------------------------------ 259 /** Sets if this local host is authorised to control the server. */ setAuthorisedToControl(bool authorised)260 void setAuthorisedToControl(bool authorised) 261 { m_authorised.store(authorised); } 262 // ------------------------------------------------------------------------ 263 std::vector<std::shared_ptr<NetworkPlayerProfile> > 264 getAllPlayerProfiles() const; 265 // ------------------------------------------------------------------------ 266 std::set<uint32_t> getAllPlayerOnlineIds() const; 267 // ------------------------------------------------------------------------ 268 std::shared_ptr<STKPeer> findPeerByHostId(uint32_t id) const; 269 // ------------------------------------------------------------------------ 270 std::shared_ptr<STKPeer> findPeerByName(const core::stringw& name) const; 271 // ------------------------------------------------------------------------ 272 void sendPacketExcept(STKPeer* peer, NetworkString *data, 273 bool reliable = true); 274 // ------------------------------------------------------------------------ 275 void setupClient(int peer_count, int channel_limit, 276 uint32_t max_incoming_bandwidth, 277 uint32_t max_outgoing_bandwidth); 278 // ------------------------------------------------------------------------ 279 void startListening(); 280 // ------------------------------------------------------------------------ 281 void stopListening(); 282 // ------------------------------------------------------------------------ 283 bool peerExists(const SocketAddress& peer_address); 284 // ------------------------------------------------------------------------ 285 std::shared_ptr<STKPeer> getServerPeerForClient() const; 286 // ------------------------------------------------------------------------ 287 void setErrorMessage(const irr::core::stringw &message); 288 // ------------------------------------------------------------------------ addEnetCommand(ENetPeer * peer,ENetPacket * packet,uint32_t i,ENetCommandType ect,ENetAddress ea)289 void addEnetCommand(ENetPeer* peer, ENetPacket* packet, uint32_t i, 290 ENetCommandType ect, ENetAddress ea) 291 { 292 std::lock_guard<std::mutex> lock(m_enet_cmd_mutex); 293 m_enet_cmd.emplace_back(peer, packet, i, ect, ea); 294 } 295 // ------------------------------------------------------------------------ 296 /** Returns the last error (or "" if no error has happened). */ getErrorMessage() const297 const irr::core::stringw& getErrorMessage() const 298 { return m_error_message; } 299 // ------------------------------------------------------------------------ 300 /** Returns true if a shutdown of the network infrastructure was 301 * requested. */ requestedShutdown() const302 bool requestedShutdown() const { return m_shutdown.load(); } 303 // ------------------------------------------------------------------------ 304 int receiveRawPacket(char *buffer, int buffer_len, 305 SocketAddress* sender, int max_tries = -1); 306 // ------------------------------------------------------------------------ 307 void sendRawPacket(const BareNetworkString &buffer, 308 const SocketAddress& dst); 309 // ------------------------------------------------------------------------ getNetwork() const310 Network* getNetwork() const { return m_network; } 311 // ------------------------------------------------------------------------ 312 /** Returns a copied list of peers. */ getPeers() const313 std::vector<std::shared_ptr<STKPeer> > getPeers() const 314 { 315 std::lock_guard<std::mutex> lock(m_peers_mutex); 316 std::vector<std::shared_ptr<STKPeer> > peers; 317 for (auto p : m_peers) 318 { 319 peers.push_back(p.second); 320 } 321 return peers; 322 } 323 // ------------------------------------------------------------------------ 324 /** Returns the next (unique) host id. */ getNextHostId() const325 unsigned int getNextHostId() const 326 { 327 assert(m_next_unique_host_id >= 0); 328 return m_next_unique_host_id; 329 } 330 // ------------------------------------------------------------------------ setNextHostId(uint32_t id)331 void setNextHostId(uint32_t id) { m_next_unique_host_id = id; } 332 // ------------------------------------------------------------------------ 333 /** Returns the number of currently connected peers. */ getPeerCount() const334 unsigned int getPeerCount() const 335 { 336 std::lock_guard<std::mutex> lock(m_peers_mutex); 337 return (unsigned)m_peers.size(); 338 } 339 // ------------------------------------------------------------------------ 340 /** Sets the global host id of this host (client use). */ setMyHostId(uint32_t my_host_id)341 void setMyHostId(uint32_t my_host_id) { m_host_id = my_host_id; } 342 // ------------------------------------------------------------------------ 343 /** Returns the host id of this host. */ getMyHostId() const344 uint32_t getMyHostId() const { return m_host_id; } 345 // ------------------------------------------------------------------------ 346 void sendToServer(NetworkString *data, bool reliable = true); 347 // ------------------------------------------------------------------------ 348 bool isClientServer() const; 349 // ------------------------------------------------------------------------ 350 void initClientNetwork(ENetEvent& event, Network* new_network); 351 // ------------------------------------------------------------------------ getPeerPings()352 std::map<uint32_t, uint32_t> getPeerPings() 353 { return m_peer_pings.getAtomic(); } 354 // ------------------------------------------------------------------------ getClientPingToServer() const355 uint32_t getClientPingToServer() const 356 { return m_client_ping.load(std::memory_order_relaxed); } 357 // ------------------------------------------------------------------------ getNetworkTimerSynchronizer() const358 NetworkTimerSynchronizer* getNetworkTimerSynchronizer() const 359 { return m_nts.get(); } 360 // ------------------------------------------------------------------------ getNetworkTimer() const361 uint64_t getNetworkTimer() const 362 { return StkTime::getMonoTimeMs() - m_network_timer.load(); } 363 // ------------------------------------------------------------------------ setNetworkTimer(uint64_t ticks)364 void setNetworkTimer(uint64_t ticks) 365 { 366 m_network_timer.store( 367 (int64_t)StkTime::getMonoTimeMs() - (int64_t)ticks); 368 } 369 // ------------------------------------------------------------------------ 370 std::pair<int, int> getAllPlayersTeamInfo() const; 371 // ------------------------------------------------------------------------ 372 /* Return upload speed in bytes per second. */ getUploadSpeed() const373 unsigned getUploadSpeed() const { return m_upload_speed.load(); } 374 // ------------------------------------------------------------------------ 375 /* Return download speed in bytes per second. */ getDownloadSpeed() const376 unsigned getDownloadSpeed() const { return m_download_speed.load(); } 377 // ------------------------------------------------------------------------ 378 void updatePlayers(unsigned* ingame = NULL, 379 unsigned* waiting = NULL, 380 unsigned* total = NULL); 381 // ------------------------------------------------------------------------ getPlayersInGame() const382 uint32_t getPlayersInGame() const { return m_players_in_game.load(); } 383 // ------------------------------------------------------------------------ getWaitingPlayers() const384 uint32_t getWaitingPlayers() const { return m_players_waiting.load(); } 385 // ------------------------------------------------------------------------ getTotalPlayers() const386 uint32_t getTotalPlayers() const { return m_total_players.load(); } 387 // ------------------------------------------------------------------------ 388 std::vector<std::shared_ptr<NetworkPlayerProfile> > 389 getPlayersForNewGame(bool* has_always_on_spectators = NULL) const; 390 // ------------------------------------------------------------------------ replaceNetwork(Network * new_network)391 void replaceNetwork(Network* new_network) 392 { 393 m_network = new_network; 394 } 395 // ------------------------------------------------------------------------ 396 static BareNetworkString getStunRequest(uint8_t* stun_tansaction_id); 397 // ------------------------------------------------------------------------ getChildLoop() const398 ChildLoop* getChildLoop() const { return m_client_loop; } 399 }; // class STKHost 400 401 #endif // STK_HOST_HPP 402