Network.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. //
  2. // Copyright (c) 2008-2017 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Container/HashSet.h"
  24. #include "../Core/Object.h"
  25. #include "../IO/VectorBuffer.h"
  26. #include "../Network/Connection.h"
  27. #include <kNet/IMessageHandler.h>
  28. #include <kNet/INetworkServerListener.h>
  29. #include <kNet/Socket.h>
  30. #ifdef SendMessage
  31. #undef SendMessage
  32. #endif
  33. namespace Atomic
  34. {
  35. class HttpRequest;
  36. class MemoryBuffer;
  37. class Scene;
  38. /// MessageConnection hash function.
  39. template <class T> unsigned MakeHash(kNet::MessageConnection* value)
  40. {
  41. return ((unsigned)(size_t)value) >> 9;
  42. }
  43. /// %Network subsystem. Manages client-server communications using the UDP protocol.
  44. class ATOMIC_API Network : public Object, public kNet::IMessageHandler, public kNet::INetworkServerListener
  45. {
  46. ATOMIC_OBJECT(Network, Object);
  47. public:
  48. /// Construct.
  49. Network(Context* context);
  50. /// Destruct.
  51. ~Network();
  52. /// Handle a kNet message from either a client or the server.
  53. virtual void HandleMessage
  54. (kNet::MessageConnection* source, kNet::packet_id_t packetId, kNet::message_id_t msgId, const char* data, size_t numBytes);
  55. /// Compute the content ID for a message.
  56. virtual u32 ComputeContentID(kNet::message_id_t msgId, const char* data, size_t numBytes);
  57. /// Handle a new client connection.
  58. virtual void NewConnectionEstablished(kNet::MessageConnection* connection);
  59. /// Handle a client disconnection.
  60. virtual void ClientDisconnected(kNet::MessageConnection* connection);
  61. /// Connect to a server using specified protocol. Return true if connection process successfully started.
  62. bool Connect(const String& address, unsigned short port, kNet::SocketTransportLayer transport, Scene* scene, const VariantMap& identity = Variant::emptyVariantMap);
  63. /// Disconnect the connection to the server. If wait time is non-zero, will block while waiting for disconnect to finish.
  64. void Disconnect(int waitMSec = 0);
  65. /// Start a server on a port using specified protocol. Return true if successful.
  66. bool StartServer(unsigned short port, kNet::SocketTransportLayer transport);
  67. /// Stop the server.
  68. void StopServer();
  69. /// Broadcast a message with content ID to all client connections.
  70. void BroadcastMessage(int msgID, bool reliable, bool inOrder, const VectorBuffer& msg, unsigned contentID = 0);
  71. /// Broadcast a message with content ID to all client connections.
  72. void BroadcastMessage
  73. (int msgID, bool reliable, bool inOrder, const unsigned char* data, unsigned numBytes, unsigned contentID = 0);
  74. /// Broadcast a remote event to all client connections.
  75. void BroadcastRemoteEvent(StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
  76. /// Broadcast a remote event to all client connections in a specific scene.
  77. void BroadcastRemoteEvent
  78. (Scene* scene, StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
  79. /// Broadcast a remote event with the specified node as a sender. Is sent to all client connections in the node's scene.
  80. void BroadcastRemoteEvent
  81. (Node* node, StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
  82. /// Set network update FPS.
  83. void SetUpdateFps(int fps);
  84. /// Set simulated latency in milliseconds. This adds a fixed delay before sending each packet.
  85. void SetSimulatedLatency(int ms);
  86. /// Set simulated packet loss probability between 0.0 - 1.0.
  87. void SetSimulatedPacketLoss(float probability);
  88. /// Register a remote event as allowed to be received. There is also a fixed blacklist of events that can not be allowed in any case, such as ConsoleCommand.
  89. void RegisterRemoteEvent(StringHash eventType);
  90. /// Unregister a remote event as allowed to received.
  91. void UnregisterRemoteEvent(StringHash eventType);
  92. /// Unregister all remote events.
  93. void UnregisterAllRemoteEvents();
  94. /// Set the package download cache directory.
  95. void SetPackageCacheDir(const String& path);
  96. /// Trigger all client connections in the specified scene to download a package file from the server. Can be used to download additional resource packages when clients are already joined in the scene. The package must have been added as a requirement to the scene, or else the eventual download will fail.
  97. void SendPackageToClients(Scene* scene, PackageFile* package);
  98. /// Perform an HTTP request to the specified URL. Empty verb defaults to a GET request. Return a request object which can be used to read the response data.
  99. SharedPtr<HttpRequest> MakeHttpRequest
  100. (const String& url, const String& verb = String::EMPTY, const Vector<String>& headers = Vector<String>(),
  101. const String& postData = String::EMPTY);
  102. /// Return network update FPS.
  103. int GetUpdateFps() const { return updateFps_; }
  104. /// Return simulated latency in milliseconds.
  105. int GetSimulatedLatency() const { return simulatedLatency_; }
  106. /// Return simulated packet loss probability.
  107. float GetSimulatedPacketLoss() const { return simulatedPacketLoss_; }
  108. /// Return a client or server connection by kNet MessageConnection, or null if none exist.
  109. Connection* GetConnection(kNet::MessageConnection* connection) const;
  110. /// Return the connection to the server. Null if not connected.
  111. Connection* GetServerConnection() const;
  112. /// Return all client connections.
  113. Vector<SharedPtr<Connection> > GetClientConnections() const;
  114. /// Return whether the server is running.
  115. bool IsServerRunning() const;
  116. /// Return whether a remote event is allowed to be received.
  117. bool CheckRemoteEvent(StringHash eventType) const;
  118. /// Return the package download cache directory.
  119. const String& GetPackageCacheDir() const { return packageCacheDir_; }
  120. /// Process incoming messages from connections. Called by HandleBeginFrame.
  121. void Update(float timeStep);
  122. /// Send outgoing messages after frame logic. Called by HandleRenderUpdate.
  123. void PostUpdate(float timeStep);
  124. // ATOMIC BEGIN
  125. friend class MasterServerClient;
  126. unsigned short GetServerPort() const { return serverPort_; }
  127. bool IsEndPointConnected(const kNet::EndPoint& endPoint) const;
  128. /// Connect to a server, reusing an existing Socket
  129. bool ConnectWithExistingSocket(kNet::Socket* existingSocket, Scene* scene);
  130. // ATOMIC END
  131. private:
  132. /// Handle begin frame event.
  133. void HandleBeginFrame(StringHash eventType, VariantMap& eventData);
  134. /// Handle render update frame event.
  135. void HandleRenderUpdate(StringHash eventType, VariantMap& eventData);
  136. /// Handle server connection.
  137. void OnServerConnected();
  138. /// Handle server disconnection.
  139. void OnServerDisconnected();
  140. /// Reconfigure network simulator parameters on all existing connections.
  141. void ConfigureNetworkSimulator();
  142. /// kNet instance.
  143. UniquePtr<kNet::Network> network_;
  144. /// Client's server connection.
  145. SharedPtr<Connection> serverConnection_;
  146. /// Server's client connections.
  147. HashMap<kNet::MessageConnection*, SharedPtr<Connection> > clientConnections_;
  148. /// Allowed remote events.
  149. HashSet<StringHash> allowedRemoteEvents_;
  150. /// Remote event fixed blacklist.
  151. HashSet<StringHash> blacklistedRemoteEvents_;
  152. /// Networked scenes.
  153. HashSet<Scene*> networkScenes_;
  154. /// Update FPS.
  155. int updateFps_;
  156. /// Simulated latency (send delay) in milliseconds.
  157. int simulatedLatency_;
  158. /// Simulated packet loss probability between 0.0 - 1.0.
  159. float simulatedPacketLoss_;
  160. /// Update time interval.
  161. float updateInterval_;
  162. /// Update time accumulator.
  163. float updateAcc_;
  164. /// Package cache directory.
  165. String packageCacheDir_;
  166. // ATOMIC BEGIN
  167. void HandleClientConnected(StringHash eventType, VariantMap& eventData);
  168. kNet::Network* GetKnetNetwork() { return network_.Get(); }
  169. unsigned short serverPort_;
  170. // ATOMIC END
  171. };
  172. /// Register Network library objects.
  173. void ATOMIC_API RegisterNetworkLibrary(Context* context);
  174. }