/// <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; }
/// <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 }); }
/// <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; }
/// <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 }); } }
/// <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; }
/// <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); } }
/// <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); } }
/// <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); }
/// <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); }
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); }
/// <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); }
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."); }