Example #1
0
 /// <summary>
 /// Unregister from a client's events.
 /// </summary>
 /// <param name="client">
 /// The client.
 /// </param>
 private void UnregisterFromEvents(MxClient client)
 {
     client.MessageSent         -= this.OnClientMessageSent;
     client.MessageReceived     -= this.OnClientMessageReceived;
     client.MessageLost         -= this.OnClientMessageLost;
     client.MessageAcknowledged -= this.OnClientMessageAcknowledged;
     client.DisconnectWarning   -= this.OnClientDisconnectWarning;
 }
Example #2
0
        /// <summary>
        /// Raise the ClientDisconnected event.
        /// </summary>
        /// <param name="client">
        /// The client.
        /// </param>
        protected virtual void OnClientDisconnected(MxClient client)
        {
            var handler = ClientDisconnected;

            handler?.Invoke(this, new MxClientEventArgs {
                Client = client
            });
        }
Example #3
0
 /// <summary>
 /// Register for a client's events.
 /// </summary>
 /// <param name="client">
 /// The client.
 /// </param>
 private void RegisterForEvents(MxClient client)
 {
     client.MessageSent         += this.OnClientMessageSent;
     client.MessageReceived     += this.OnClientMessageReceived;
     client.MessageLost         += this.OnClientMessageLost;
     client.MessageAcknowledged += this.OnClientMessageAcknowledged;
     client.DisconnectWarning   += this.OnClientDisconnectWarning;
 }
Example #4
0
        /// <summary>
        /// Raise the ClientDisconnected event.
        /// </summary>
        /// <param name="client">
        /// The client.
        /// </param>
        protected virtual void OnClientDisconnected(MxClient client)
        {
            var handler = this.ClientDisconnected;

            if (handler != null)
            {
                handler(this, new MxClientEventArgs {
                    Client = client
                });
            }
        }
Example #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MxReliability"/> class.
        /// </summary>
        /// <param name="client">
        /// The client that this reliability class is associated with.
        /// </param>
        public MxReliability(MxClient client)
        {
            this.m_Client = client;

            this.m_QueuedMessages = new Queue <byte[]>();
            this.m_ActiveMessages = new List <MxReliabilitySendState>();

            this.m_ActiveReceiveMessages = new Dictionary <int, MxReliabilityReceiveState>();

            this.m_Client.MessageAcknowledged += this.ClientOnMessageAcknowledged;
            this.m_Client.MessageLost         += this.ClientOnMessageLost;
            this.m_Client.MessageReceived     += this.ClientOnMessageReceived;
        }
Example #6
0
        /// <summary>
        /// Queue a packet for sending to the specified client.
        /// </summary>
        /// <param name="client">
        /// The client to send the message to.
        /// </param>
        /// <param name="packet">
        /// The associated data to send.
        /// </param>
        /// <param name="reliable">
        /// Whether or not this message should be sent reliably and intact.  This also
        /// permits messages larger than 512 bytes to be sent.
        /// </param>
        public void Send(MxClient client, byte[] packet, bool reliable = false)
        {
            AssertNotClosed();

            if (!reliable)
            {
                client.EnqueueSend(packet, MxMessage.RealtimeProtocol);
            }
            else
            {
                var reliability = client.Group.ReliableClients.First(x => x.Client == client);
                reliability.Send(packet);
            }
        }
Example #7
0
 /// <summary>
 /// Internally handles propagating network messages to the networked components on the client.
 /// </summary>
 /// <param name="component"></param>
 /// <param name="gameContext"></param>
 /// <param name="updateContext"></param>
 /// <param name="dispatcher"></param>
 /// <param name="client"></param>
 /// <param name="payload"></param>
 /// <param name="protocolId"></param>
 /// <param name="eventState"></param>
 private void ClientMessageCallback(
     INetworkedComponent component,
     IGameContext gameContext,
     IUpdateContext updateContext,
     MxDispatcher dispatcher,
     MxClient client,
     byte[] payload,
     uint protocolId,
     EventState eventState)
 {
     if (!eventState.Consumed)
     {
         eventState.Consumed = component.ReceiveMessage(this, gameContext,
                                                        updateContext,
                                                        dispatcher,
                                                        client,
                                                        payload,
                                                        protocolId);
     }
 }
Example #8
0
        /// <summary>
        /// Disconnects the specified Mx client.  This removes it from
        /// the group that owns it, and prevents it from reconnecting to
        /// this dispatcher implicitly.
        /// </summary>
        /// <param name="client">The client.</param>
        public void Disconnect(MxClient client)
        {
            AssertNotClosed();

            lock (_mxClientGroupLock)
            {
                var reliability = client.Group.ReliableClients.First(x => x.Client == client);

                var group = client.Group;
                group.RealtimeClients.Remove(client);
                group.ReliableClients.Remove(reliability);

                UnregisterFromEvents(client);
                UnregisterFromEvents(reliability);

                _explicitlyDisconnected.Add(client.Endpoint);
            }

            OnClientDisconnected(client);
        }
Example #9
0
        /// <summary>
        /// Places the specified Mx client in the specified group.
        /// </summary>
        /// <param name="client">The Mx client.</param>
        /// <param name="identifier">The group identifier.</param>
        public MxClientGroup PlaceInGroup(MxClient client, string identifier)
        {
            if (client.Group.Identifier == identifier)
            {
                return(client.Group);
            }

            if (!_mxClientGroups.ContainsKey(identifier))
            {
                _mxClientGroups[identifier] = new MxClientGroup(this, identifier);
            }

            var reliability = client.Group.ReliableClients.First(x => x.Client == client);

            client.Group.RealtimeClients.Remove(client);
            client.Group.ReliableClients.Remove(reliability);
            client.Group = _mxClientGroups[identifier];
            client.Group.RealtimeClients.Add(client);
            client.Group.ReliableClients.Add(reliability);

            return(client.Group);
        }
Example #10
0
        private MxClient ThreadSafeGetOrCreateClient(IPEndPoint endpoint)
        {
            MxClient client;

            lock (_mxClientGroupLock)
            {
                client =
                    _mxClientGroups
                    .Select(x => x.Value.RealtimeClients.FirstOrDefault(y => y.Endpoint.ToString() == endpoint.ToString()))
                    .FirstOrDefault(x => x != null);
                if (client != null)
                {
                    return(client);
                }

                if (_explicitlyDisconnected.Contains(endpoint))
                {
                    return(null);
                }

                client = new MxClient(
                    this,
                    _mxClientGroups[MxClientGroup.Ungrouped],
                    endpoint,
                    _udpClient);
                _mxClientGroups[MxClientGroup.Ungrouped].RealtimeClients.Add(client);
                RegisterForEvents(client);

                var reliability = new MxReliability(client);
                _mxClientGroups[MxClientGroup.Ungrouped].ReliableClients.Add(reliability);
                RegisterForEvents(reliability);
            }

            OnClientConnected(client);

            return(client);
        }
Example #11
0
 /// <summary>
 /// Called by the network engine when this entity is spawned with an <see cref="EntityPredictMessage"/>.
 /// </summary>
 /// <param name="serverContext"></param>
 /// <param name="updateContext"></param>
 /// <param name="client"></param>
 /// <param name="predictedIdentifier"></param>
 public virtual void ReceivePredictedNetworkIDFromClient(IServerContext serverContext, IUpdateContext updateContext, MxClient client,
                                                         int predictedIdentifier)
 {
     if (EnabledInterfaces.Contains(typeof(INetworkIdentifiable)))
     {
         _networkIdentifiableServer.Invoke(serverContext, updateContext, client, predictedIdentifier);
     }
 }
 public void ReceivePredictedNetworkIDFromClient(IServerContext serverContext, IUpdateContext updateContext, MxClient client,
                                                 int predictedIdentifier)
 {
     if (!_enabled)
     {
         return;
     }
 }
        public bool ReceiveMessage(ComponentizedEntity entity, IServerContext serverContext, IUpdateContext updateContext, MxDispatcher dispatcher, MxClient client, byte[] payload, uint protocolId)
        {
            if (!_enabled)
            {
                return(false);
            }

            if (_uniqueIdentifierForEntity == null)
            {
                return(false);
            }

            // See what kind of messages we accept, based on the client authority.
            switch (ClientAuthoritiveMode)
            {
            case ClientAuthoritiveMode.None:
                // We don't accept any client data about this entity, so ignore it.
                return(false);

            case ClientAuthoritiveMode.TrustClient:
            {
                // Check to see if the message is coming from a client that has authority.
                if (ClientOwnership != null && ClientOwnership != client.Group)
                {
                    // We don't trust this message.
                    return(false);
                }

                // We trust the client, so process this information like a client would.
                var propertyMessage = _networkMessageSerialization.Deserialize(payload) as EntityPropertiesMessage;

                if (propertyMessage == null || propertyMessage.EntityID != _uniqueIdentifierForEntity.Value)
                {
                    return(false);
                }

                // If the entity is a synchronised entity, collect properties of the synchronised object
                // directly.
                var synchronisedEntity = entity as ISynchronisedObject;
                if (synchronisedEntity != null)
                {
                    _synchronisationContext = synchronisedEntity;
                    _synchronisationContext.DeclareSynchronisedProperties(this);
                }

                // Iterate through all the components on the entity and get their synchronisation data as well.
                foreach (var synchronisedComponent in entity.Components.OfType <ISynchronisedObject>())
                {
                    _synchronisationContext = synchronisedComponent;
                    _synchronisationContext.DeclareSynchronisedProperties(this);
                }

                AssignMessageToSyncData(propertyMessage, _synchronisedData, client.Group);
                return(true);
            }

            case ClientAuthoritiveMode.ReplayInputs:
                // We don't implement this yet, but we don't want to allow client packets to cause
                // a server error, so silently consume it.
                return(false);
            }

            return(false);
        }
        public bool ReceiveMessage(ComponentizedEntity entity, IGameContext gameContext, IUpdateContext updateContext, MxDispatcher dispatcher, MxClient server,
                                   byte[] payload, uint protocolId)
        {
            if (!_enabled)
            {
                return(false);
            }

            if (_uniqueIdentifierForEntity == null)
            {
                return(false);
            }

            var propertyMessage = _networkMessageSerialization.Deserialize(payload) as EntityPropertiesMessage;

            if (propertyMessage == null || propertyMessage.EntityID != _uniqueIdentifierForEntity.Value)
            {
                return(false);
            }

            // If the entity is a synchronised entity, collect properties of the synchronised object
            // directly.
            var synchronisedEntity = entity as ISynchronisedObject;

            if (synchronisedEntity != null)
            {
                _synchronisationContext = synchronisedEntity;
                _synchronisationContext.DeclareSynchronisedProperties(this);
            }

            // Iterate through all the components on the entity and get their synchronisation data as well.
            foreach (var synchronisedComponent in entity.Components.OfType <ISynchronisedObject>())
            {
                _synchronisationContext = synchronisedComponent;
                _synchronisationContext.DeclareSynchronisedProperties(this);
            }

            AssignMessageToSyncData(propertyMessage, _synchronisedData, server.Group);
            return(true);
        }
Example #15
0
 public void ReceivePredictedNetworkIDFromClient(IServerContext serverContext, IUpdateContext updateContext, MxClient client,
                                                 int predictedIdentifier)
 {
     throw new InvalidOperationException(
               "Entity groups can not receive predicted network IDs.  This indicates an error in the code.");
 }