| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- //
- // Copyright (c) 2008-2017 the Urho3D project.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- #pragma once
- #include "../Container/HashSet.h"
- #include "../Core/Object.h"
- #include "../IO/VectorBuffer.h"
- #include "../Network/Connection.h"
- #include <kNet/IMessageHandler.h>
- #include <kNet/INetworkServerListener.h>
- #include <kNet/Socket.h>
- #ifdef SendMessage
- #undef SendMessage
- #endif
- namespace Atomic
- {
- class HttpRequest;
- class MemoryBuffer;
- class Scene;
- /// MessageConnection hash function.
- template <class T> unsigned MakeHash(kNet::MessageConnection* value)
- {
- return ((unsigned)(size_t)value) >> 9;
- }
- /// %Network subsystem. Manages client-server communications using the UDP protocol.
- class ATOMIC_API Network : public Object, public kNet::IMessageHandler, public kNet::INetworkServerListener
- {
- ATOMIC_OBJECT(Network, Object);
- public:
- /// Construct.
- Network(Context* context);
- /// Destruct.
- ~Network();
- /// Handle a kNet message from either a client or the server.
- virtual void HandleMessage
- (kNet::MessageConnection* source, kNet::packet_id_t packetId, kNet::message_id_t msgId, const char* data, size_t numBytes);
- /// Compute the content ID for a message.
- virtual u32 ComputeContentID(kNet::message_id_t msgId, const char* data, size_t numBytes);
- /// Handle a new client connection.
- virtual void NewConnectionEstablished(kNet::MessageConnection* connection);
- /// Handle a client disconnection.
- virtual void ClientDisconnected(kNet::MessageConnection* connection);
- /// Connect to a server using specified protocol. Return true if connection process successfully started.
- bool Connect(const String& address, unsigned short port, kNet::SocketTransportLayer transport, Scene* scene, const VariantMap& identity = Variant::emptyVariantMap);
- /// Disconnect the connection to the server. If wait time is non-zero, will block while waiting for disconnect to finish.
- void Disconnect(int waitMSec = 0);
- /// Start a server on a port using specified protocol. Return true if successful.
- bool StartServer(unsigned short port, kNet::SocketTransportLayer transport);
- /// Stop the server.
- void StopServer();
- /// Broadcast a message with content ID to all client connections.
- void BroadcastMessage(int msgID, bool reliable, bool inOrder, const VectorBuffer& msg, unsigned contentID = 0);
- /// Broadcast a message with content ID to all client connections.
- void BroadcastMessage
- (int msgID, bool reliable, bool inOrder, const unsigned char* data, unsigned numBytes, unsigned contentID = 0);
- /// Broadcast a remote event to all client connections.
- void BroadcastRemoteEvent(StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
- /// Broadcast a remote event to all client connections in a specific scene.
- void BroadcastRemoteEvent
- (Scene* scene, StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
- /// Broadcast a remote event with the specified node as a sender. Is sent to all client connections in the node's scene.
- void BroadcastRemoteEvent
- (Node* node, StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
- /// Set network update FPS.
- void SetUpdateFps(int fps);
- /// Set simulated latency in milliseconds. This adds a fixed delay before sending each packet.
- void SetSimulatedLatency(int ms);
- /// Set simulated packet loss probability between 0.0 - 1.0.
- void SetSimulatedPacketLoss(float probability);
- /// 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.
- void RegisterRemoteEvent(StringHash eventType);
- /// Unregister a remote event as allowed to received.
- void UnregisterRemoteEvent(StringHash eventType);
- /// Unregister all remote events.
- void UnregisterAllRemoteEvents();
- /// Set the package download cache directory.
- void SetPackageCacheDir(const String& path);
- /// 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.
- void SendPackageToClients(Scene* scene, PackageFile* package);
- /// 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.
- SharedPtr<HttpRequest> MakeHttpRequest
- (const String& url, const String& verb = String::EMPTY, const Vector<String>& headers = Vector<String>(),
- const String& postData = String::EMPTY);
- /// Return network update FPS.
- int GetUpdateFps() const { return updateFps_; }
- /// Return simulated latency in milliseconds.
- int GetSimulatedLatency() const { return simulatedLatency_; }
- /// Return simulated packet loss probability.
- float GetSimulatedPacketLoss() const { return simulatedPacketLoss_; }
- /// Return a client or server connection by kNet MessageConnection, or null if none exist.
- Connection* GetConnection(kNet::MessageConnection* connection) const;
- /// Return the connection to the server. Null if not connected.
- Connection* GetServerConnection() const;
- /// Return all client connections.
- Vector<SharedPtr<Connection> > GetClientConnections() const;
- /// Return whether the server is running.
- bool IsServerRunning() const;
- /// Return whether a remote event is allowed to be received.
- bool CheckRemoteEvent(StringHash eventType) const;
- /// Return the package download cache directory.
- const String& GetPackageCacheDir() const { return packageCacheDir_; }
- /// Process incoming messages from connections. Called by HandleBeginFrame.
- void Update(float timeStep);
- /// Send outgoing messages after frame logic. Called by HandleRenderUpdate.
- void PostUpdate(float timeStep);
- // ATOMIC BEGIN
- friend class MasterServerClient;
- unsigned short GetServerPort() const { return serverPort_; }
- bool IsEndPointConnected(const kNet::EndPoint& endPoint) const;
- /// Connect to a server, reusing an existing Socket
- bool ConnectWithExistingSocket(kNet::Socket* existingSocket, Scene* scene);
- // ATOMIC END
- private:
- /// Handle begin frame event.
- void HandleBeginFrame(StringHash eventType, VariantMap& eventData);
- /// Handle render update frame event.
- void HandleRenderUpdate(StringHash eventType, VariantMap& eventData);
- /// Handle server connection.
- void OnServerConnected();
- /// Handle server disconnection.
- void OnServerDisconnected();
- /// Reconfigure network simulator parameters on all existing connections.
- void ConfigureNetworkSimulator();
- /// kNet instance.
- UniquePtr<kNet::Network> network_;
- /// Client's server connection.
- SharedPtr<Connection> serverConnection_;
- /// Server's client connections.
- HashMap<kNet::MessageConnection*, SharedPtr<Connection> > clientConnections_;
- /// Allowed remote events.
- HashSet<StringHash> allowedRemoteEvents_;
- /// Remote event fixed blacklist.
- HashSet<StringHash> blacklistedRemoteEvents_;
- /// Networked scenes.
- HashSet<Scene*> networkScenes_;
- /// Update FPS.
- int updateFps_;
- /// Simulated latency (send delay) in milliseconds.
- int simulatedLatency_;
- /// Simulated packet loss probability between 0.0 - 1.0.
- float simulatedPacketLoss_;
- /// Update time interval.
- float updateInterval_;
- /// Update time accumulator.
- float updateAcc_;
- /// Package cache directory.
- String packageCacheDir_;
- // ATOMIC BEGIN
-
- void HandleClientConnected(StringHash eventType, VariantMap& eventData);
- kNet::Network* GetKnetNetwork() { return network_.Get(); }
- unsigned short serverPort_;
- // ATOMIC END
- };
- /// Register Network library objects.
- void ATOMIC_API RegisterNetworkLibrary(Context* context);
- }
|