public MessageTypeDescription(ushort messageTypeId, Type messageType, int sequenceChannel, NetDeliveryMethod deliveryMethod)
 {
     _messageTypeId = messageTypeId;
     _messageType = messageType;
     _sequenceChannel = sequenceChannel;
     _deliveryMethod = deliveryMethod;
 }
        /// <summary>
        /// Send a message to a specific connection
        /// </summary>
        /// <param name="msg">The message to send</param>
        /// <param name="recipient">The recipient connection</param>
        /// <param name="method">How to deliver the message</param>
        /// <param name="sequenceChannel">Sequence channel within the delivery method</param>
        public NetSendResult SendMessage(NetOutgoingMessage msg, NetConnection recipient, NetDeliveryMethod method, int sequenceChannel)
        {
            if (msg == null)
                throw new ArgumentNullException("msg");
            if (recipient == null)
                throw new ArgumentNullException("recipient");

            NetException.Assert(
                ((method != NetDeliveryMethod.Unreliable && method != NetDeliveryMethod.ReliableUnordered) ||
                ((method == NetDeliveryMethod.Unreliable || method == NetDeliveryMethod.ReliableUnordered) && sequenceChannel == 0)),
                "Delivery method " + method + " cannot use sequence channels other than 0!"
            );

            NetException.Assert(method != NetDeliveryMethod.Unknown, "Bad delivery method!");

            if (msg.m_isSent)
                throw new NetException("This message has already been sent! Use NetPeer.SendMessage() to send to multiple recipients efficiently");

            int len = msg.LengthBytes;
            if (len <= m_configuration.MaximumTransmissionUnit)
            {
                Interlocked.Increment(ref msg.m_recyclingCount);
                return recipient.EnqueueMessage(msg, method, sequenceChannel);
            }
            else
            {
                // message must be fragmented!
                SendFragmentedMessage(msg, new NetConnection[] { recipient }, method, sequenceChannel);
                return NetSendResult.Queued; // could be different for each connection; Queued is "most true"
            }
        }
Beispiel #3
0
        /// <summary>
        /// Send a message to a specific connection
        /// </summary>
        /// <param name="msg">The message to send</param>
        /// <param name="recipient">The recipient connection</param>
        /// <param name="method">How to deliver the message</param>
        /// <param name="sequenceChannel">Sequence channel within the delivery method</param>
        public NetSendResult SendMessage(NetOutgoingMessage msg, NetConnection recipient, NetDeliveryMethod method, int sequenceChannel)
        {
            if (msg == null)
                throw new ArgumentNullException("msg");
            if (recipient == null)
                throw new ArgumentNullException("recipient");
            if (sequenceChannel >= NetConstants.NetChannelsPerDeliveryMethod)
                throw new ArgumentOutOfRangeException("sequenceChannel");

            NetException.Assert(
                ((method != NetDeliveryMethod.Unreliable && method != NetDeliveryMethod.ReliableUnordered) ||
                ((method == NetDeliveryMethod.Unreliable || method == NetDeliveryMethod.ReliableUnordered) && sequenceChannel == 0)),
                "Delivery method " + method + " cannot use sequence channels other than 0!"
            );

            NetException.Assert(method != NetDeliveryMethod.Unknown, "Bad delivery method!");

            if (msg.m_isSent)
                throw new NetException("This message has already been sent! Use NetPeer.SendMessage() to send to multiple recipients efficiently");
            msg.m_isSent = true;

            int len = NetConstants.UnfragmentedMessageHeaderSize + msg.LengthBytes; // headers + length, faster than calling msg.GetEncodedSize
            if (len <= recipient.m_currentMTU)
            {
                Interlocked.Increment(ref msg.m_recyclingCount);
                return recipient.EnqueueMessage(msg, method, sequenceChannel);
            }
            else
            {
                // message must be fragmented!
                SendFragmentedMessage(msg, new NetConnection[] { recipient }, method, sequenceChannel);
                return NetSendResult.Queued; // could be different for each connection; Queued is "most true"
            }
        }
        public void SendMessage(NetOutgoingMessage msg, IList<NetConnection> recipients, NetDeliveryMethod method, int sequenceChannel)
        {
            if (msg == null)
                throw new ArgumentNullException("msg");
            if (recipients == null)
                throw new ArgumentNullException("recipients");
            if (method == NetDeliveryMethod.Unreliable || method == NetDeliveryMethod.ReliableUnordered)
                NetException.Assert(sequenceChannel == 0, "Delivery method " + method + " cannot use sequence channels other than 0!");
            if (msg.m_isSent)
                throw new NetException("This message has already been sent! Use NetPeer.SendMessage() to send to multiple recipients efficiently");

            int len = msg.LengthBytes;
            if (len <= m_configuration.MaximumTransmissionUnit)
            {
                Interlocked.Add(ref msg.m_recyclingCount, recipients.Count);
                foreach (NetConnection conn in recipients)
                {
                    if (conn == null)
                    {
                        Interlocked.Decrement(ref msg.m_recyclingCount);
                        continue;
                    }
                    NetSendResult res = conn.EnqueueMessage(msg, method, sequenceChannel);
                    if (res == NetSendResult.Dropped)
                        Interlocked.Decrement(ref msg.m_recyclingCount);
                }
            }
            else
            {
                // message must be fragmented!
                SendFragmentedMessage(msg, recipients, method, sequenceChannel);
            }

            return;
        }
		// on user thread
		private NetSendResult SendFragmentedMessage(NetOutgoingMessage msg, IList<NetConnection> recipients, NetDeliveryMethod method, int sequenceChannel)
		{
			// Note: this group id is PER SENDING/NetPeer; ie. same id is sent to all recipients;
			// this should be ok however; as long as recipients differentiate between same id but different sender
			int group = Interlocked.Increment(ref m_lastUsedFragmentGroup);
			if (group >= NetConstants.MaxFragmentationGroups)
			{
				// @TODO: not thread safe; but in practice probably not an issue
				m_lastUsedFragmentGroup = 1;
				group = 1;
			}
			msg.m_fragmentGroup = group;

			// do not send msg; but set fragmentgroup in case user tries to recycle it immediately

			// create fragmentation specifics
			int totalBytes = msg.LengthBytes;

			// determine minimum mtu for all recipients
			int mtu = GetMTU(recipients);
			int bytesPerChunk = NetFragmentationHelper.GetBestChunkSize(group, totalBytes, mtu);

			int numChunks = totalBytes / bytesPerChunk;
			if (numChunks * bytesPerChunk < totalBytes)
				numChunks++;

			NetSendResult retval = NetSendResult.Sent;

			int bitsPerChunk = bytesPerChunk * 8;
			int bitsLeft = msg.LengthBits;
			for (int i = 0; i < numChunks; i++)
			{
				NetOutgoingMessage chunk = CreateMessage(0);

				chunk.m_bitLength = (bitsLeft > bitsPerChunk ? bitsPerChunk : bitsLeft);
				chunk.m_data = msg.m_data;
				chunk.m_fragmentGroup = group;
				chunk.m_fragmentGroupTotalBits = totalBytes * 8;
				chunk.m_fragmentChunkByteSize = bytesPerChunk;
				chunk.m_fragmentChunkNumber = i;

				NetException.Assert(chunk.m_bitLength != 0);
				NetException.Assert(chunk.GetEncodedSize() < mtu);

				Interlocked.Add(ref chunk.m_recyclingCount, recipients.Count);

				foreach (NetConnection recipient in recipients)
				{
					var res = recipient.EnqueueMessage(chunk, method, sequenceChannel);
					if (res == NetSendResult.Dropped)
						Interlocked.Decrement(ref chunk.m_recyclingCount);
					if ((int)res > (int)retval)
						retval = res; // return "worst" result
				}

				bitsLeft -= bitsPerChunk;
			}

			return retval;
		}
Beispiel #6
0
		/// <summary>
		/// Send a message to all connections
		/// </summary>
		/// <param name="msg">The message to send</param>
		/// <param name="method">How to deliver the message</param>
		public void SendToAll(NetOutgoingMessage msg, NetDeliveryMethod method)
		{
			var all = this.Connections;
			if (all.Count <= 0)
				return;

			SendMessage(msg, all, method, 0);
		}
Beispiel #7
0
 public void Reply(NetDeliveryMethod method)
 {
     if (CanReply) {
         this.Send(LastReceivedSender, method);
     } else {
         throw new Exception("Can only reply in 'Execute' method of a Message."); //It's the only way we know who to reply to.
     }
 }
Beispiel #8
0
        // called by the UI
        internal static void Connect(string host, int port, string deliveryMethod, int sequenceChannel)
        {
            s_client.Start();

            s_method = (NetDeliveryMethod)Enum.Parse(typeof(NetDeliveryMethod), deliveryMethod);
            s_sequenceChannel = sequenceChannel;

            s_client.Connect(host, port);
        }
		/// <summary>
		/// Send a message to all connections
		/// </summary>
		/// <param name="msg">The message to send</param>
		/// <param name="method">How to deliver the message</param>
		public void SendToAll(NetOutgoingMessage msg, NetDeliveryMethod method)
		{
			var all = this.Connections;
			if (all.Count <= 0) {
				if (msg.m_isSent == false)
					Recycle(msg);
				return;
			}

			SendMessage(msg, all, method, 0);
		}
		internal NetUnreliableSenderChannel(NetConnection connection, int windowSize, NetDeliveryMethod method)
		{
			m_connection = connection;
			m_windowSize = windowSize;
			m_windowStart = 0;
			m_sendStart = 0;
			m_receivedAcks = new NetBitVector(NetConstants.NumSequenceNumbers);
			m_queuedSends = new NetQueue<NetOutgoingMessage>(8);

			m_doFlowControl = true;
			if (method == NetDeliveryMethod.Unreliable && connection.Peer.Configuration.SuppressUnreliableUnorderedAcks == true)
				m_doFlowControl = false;
		}
 public bool SendMessage(NetOutgoingMessage message, NetDeliveryMethod method, ChannelTypes channelType)
 {
     if (_netClient.ConnectionStatus == NetConnectionStatus.Connected)
     {
         _netClient.SendMessage(message, method, (int)channelType);
         return true;
     }
     else
     {
         _packetCache.Add(new Tuple<NetOutgoingMessage, NetDeliveryMethod, ChannelTypes>(message, method, channelType));
         return false;
     }
 }
		// on user thread
		private void SendFragmentedMessage(NetOutgoingMessage msg, IList<NetConnection> recipients, NetDeliveryMethod method, int sequenceChannel)
		{
			int group = Interlocked.Increment(ref m_lastUsedFragmentGroup);
			if (group >= NetConstants.MaxFragmentationGroups)
			{
				// TODO: not thread safe; but in practice probably not an issue
				m_lastUsedFragmentGroup = 1;
				group = 1;
			}
			msg.m_fragmentGroup = group;

			// do not send msg; but set fragmentgroup in case user tries to recycle it immediately

			// create fragmentation specifics
			int totalBytes = msg.LengthBytes;

			// determine minimum mtu for all recipients
			int mtu = GetMTU(recipients);
			int bytesPerChunk = NetFragmentationHelper.GetBestChunkSize(group, totalBytes, mtu);

			int numChunks = totalBytes / bytesPerChunk;
			if (numChunks * bytesPerChunk < totalBytes)
				numChunks++;

			int bitsPerChunk = bytesPerChunk * 8;
			int bitsLeft = msg.LengthBits;
			for (int i = 0; i < numChunks; i++)
			{
				NetOutgoingMessage chunk = CreateMessage(mtu);

				chunk.m_bitLength = (bitsLeft > bitsPerChunk ? bitsPerChunk : bitsLeft);
				chunk.m_data = msg.m_data;
				chunk.m_fragmentGroup = group;
				chunk.m_fragmentGroupTotalBits = totalBytes * 8;
				chunk.m_fragmentChunkByteSize = bytesPerChunk;
				chunk.m_fragmentChunkNumber = i;

				NetException.Assert(chunk.m_bitLength != 0);
				NetException.Assert(chunk.GetEncodedSize() < mtu);

				Interlocked.Add(ref chunk.m_recyclingCount, recipients.Count);

				foreach (NetConnection recipient in recipients)
					recipient.EnqueueMessage(chunk, method, sequenceChannel);

				bitsLeft -= bitsPerChunk;
			}

			return;
		}
Beispiel #13
0
        /// <summary>
        /// Send a message to all connections except one
        /// </summary>
        /// <param name="msg">The message to send</param>
        /// <param name="method">How to deliver the message</param>
        /// <param name="except">Don't send to this particular connection</param>
        /// <param name="sequenceChannel">Which sequence channel to use for the message</param>
        public void SendToAll(NetOutgoingMessage msg, NetConnection except, NetDeliveryMethod method, int sequenceChannel)
        {
            var all = this.Connections;
            if (all.Count <= 0)
                return;

            List<NetConnection> recipients = new List<NetConnection>(all.Count - 1);
            foreach (var conn in all)
                if (conn != except)
                    recipients.Add(conn);

            if (recipients.Count > 0)
                SendMessage(msg, recipients, method, sequenceChannel);
        }
        public void SendNetworkMessage(Message message, SendTo sendTo, NetIncomingMessage netMessage = null, NetDeliveryMethod deliveryMethod = NetDeliveryMethod.ReliableOrdered)
        {
            if (m_isServer)
            {
                Type messageType = message.GetType();
                NetOutgoingMessage om = m_server.CreateMessage();
                om.Write((int)MessageFunction.ClassMessage);;
                om.Write(messageType.Assembly.ToString());
                om.Write(messageType.ToString());
                om.WriteAllFields(message);

                NetConnection sender = null;
                if (netMessage != null)
                {
                    sender = netMessage.SenderConnection;
                }

                switch (sendTo)
                {
                    case SendTo.All:
                        message.OnCalled(message, netMessage);
                        m_server.SendToAll(om, sender, deliveryMethod, 0);
                        break;
                    case SendTo.Others:
                        m_server.SendToAll(om, sender, deliveryMethod, 0);
                        if (sender != null)  //If server diden't send the message
                            message.OnCalled(message, netMessage);
                        break;
                    case SendTo.Server:
                        message.OnCalled(message, netMessage);
                        break;
                }
            }
            else
            {
                Type messageType = message.GetType();
                NetOutgoingMessage om = m_client.CreateMessage();
                om.Write((int)MessageFunction.ClassMessage);
                om.Write((int) sendTo);
                om.Write(messageType.Assembly.ToString());
                om.Write(messageType.ToString());
                om.WriteAllFields(message);
                m_client.SendMessage(om, deliveryMethod);

                if (sendTo == SendTo.All) //Trigger for sender if you sent it to everybody
                {
                    message.OnCalled(message, netMessage);
                }
            }
        }
Beispiel #15
0
        /// <summary>
        /// Send a message to a list of connections
        /// </summary>
        /// <param name="msg">The message to send</param>
        /// <param name="recipients">The list of recipients to send to</param>
        /// <param name="method">How to deliver the message</param>
        /// <param name="sequenceChannel">Sequence channel within the delivery method</param>
        public void SendMessage(INetOutgoingMessage msg, IList<INetConnection> recipients, NetDeliveryMethod method, int sequenceChannel)
        {
            NetOutgoingMessage _msg = (NetOutgoingMessage)msg;
            if (msg == null)
                throw new ArgumentNullException("msg");
            if (recipients == null)
            {
                if (_msg.m_isSent == false)
                    Recycle(_msg);
                throw new ArgumentNullException("recipients");
            }
            if (recipients.Count < 1)
            {
                if (_msg.m_isSent == false)
                    Recycle(_msg);
                throw new NetException("recipients must contain at least one item");
            }
            if (method == NetDeliveryMethod.Unreliable || method == NetDeliveryMethod.ReliableUnordered)
                NetException.Assert(sequenceChannel == 0, "Delivery method " + method + " cannot use sequence channels other than 0!");
            if (_msg.m_isSent)
                throw new NetException("This message has already been sent! Use NetPeer.SendMessage() to send to multiple recipients efficiently");
            _msg.m_isSent = true;

            int mtu = GetMTU(recipients);

            int len = _msg.GetEncodedSize();
            if (len <= mtu)
            {
                Interlocked.Add(ref _msg.m_recyclingCount, recipients.Count);
                foreach (NetConnection conn in recipients)
                {
                    if (conn == null)
                    {
                        Interlocked.Decrement(ref _msg.m_recyclingCount);
                        continue;
                    }
                    NetSendResult res = conn.EnqueueMessage(_msg, method, sequenceChannel);
                    if (res == NetSendResult.Dropped)
                        Interlocked.Decrement(ref _msg.m_recyclingCount);
                }
            }
            else
            {
                // message must be fragmented!
                SendFragmentedMessage(_msg, recipients, method, sequenceChannel);
            }

            return;
        }
        /// <summary>
        /// Zero windowSize indicates that the channel is not yet instantiated (used)
        /// Negative freeWindowSlots means this amount of messages are currently queued but delayed due to closed window
        /// </summary>
        public void GetSendQueueInfo(NetDeliveryMethod method, int sequenceChannel, out int windowSize, out int freeWindowSlots)
        {
            int channelSlot = (int)method - 1 + sequenceChannel;
            var chan        = m_sendChannels[channelSlot];

            if (chan == null)
            {
                windowSize      = NetUtility.GetWindowSize(method);
                freeWindowSlots = windowSize;
                return;
            }

            windowSize      = chan.WindowSize;
            freeWindowSlots = chan.GetFreeWindowSlots();
            return;
        }
Beispiel #17
0
        void sendStream(Player player, NetConnection connection, NetDeliveryMethod delivery, ByteOutStream data, ByteOutStream header, int mtu)
        {
            // Create message
            NetOutgoingMessage message = Peer.CreateMessage(Math.Max(mtu, data.Size + header.Size));

            // Write header + data
            message.WriteRaw(header.Stream.Data, 0, header.Stream.Size);
            message.WriteRaw(data.Stream.Data, 0, data.Stream.Size);

            // Record status
            player.Stats.AddOutBytes(message.LengthBytes + 2);
            player.Context.Stats.AddOutBytes(message.LengthBytes + 2);

            // Send message
            Peer.SendMessage(message, connection, delivery);
        }
Beispiel #18
0
        public bool Send <T>(T packet, int capacity, NetConnection recipient, NetDeliveryMethod method, int channel) where T : struct, IServerPacket
        {
            NetOutgoingMessage msg = server.CreateMessage(capacity);

            msg.Write((byte)packet.Type);
            packet.Write(msg);
            NetSendResult result = server.Send(msg, recipient, method, channel);

#if NETWORK_DEBUG__
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.Write("Debug: ");
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine("Send<" + typeof(T).Name + ">  " + msg.LengthBytes + " bytes");
#endif
            return(result == NetSendResult.Sent || result == NetSendResult.Queued);
        }
        /// <summary>
        /// Send a message to all connections
        /// </summary>
        /// <param name="msg">The message to send</param>
        /// <param name="method">How to deliver the message</param>
        public void SendToAll(NetOutgoingMessage msg, NetDeliveryMethod method)
        {
            // Modifying m_connections will modify the list of the connections of the NetPeer. Do only reads here
            var all = m_connections;

            if (all.Count <= 0)
            {
                if (msg.m_isSent == false)
                {
                    Recycle(msg);
                }
                return;
            }

            SendMessage(msg, all, method, 0);
        }
Beispiel #20
0
        /// <summary>
        /// Send a message through this connection.
        /// </summary>
        /// <param name="data">Binary data</param>
        /// <param name="method">UDP delivery method (ignored if sent over TCP
        /// because of message size)</param>
        /// <param name="channel">Channel</param>
        public void SendMessage(ref byte[] data, NetDeliveryMethod method, int channel)
        {
            if (data.Length > _MaxMessageSize)
            {
                SendCompressedMessage(ref data);

                return;
            }

            NetOutgoingMessage message = NetConnection.Peer.CreateMessage(data.Length);

            message.LengthBytes = data.Length;
            message.Data        = data;

            NetConnection.SendMessage(message, method, channel);
        }
Beispiel #21
0
        public void SendMessage(NetOutgoingMessage mes, NetDeliveryMethod method = NetDeliveryMethod.Unreliable)
        {
            if (servercon == null)
            {
                waitConnection();
            }

            if (servercon.Status == NetConnectionStatus.Disconnected)
            {
                PloobsEngine.Engine.Logger.ActiveLogger.LogMessage("Connection lost " + servercon.ToString(), Engine.Logger.LogLevel.Warning);
                client.Connect(servercon.RemoteEndpoint);
                waitConnection();
            }

            client.SendMessage(mes, servercon, method);
        }
        /// <summary>
        /// Send a message to a specific connection.
        /// </summary>
        /// <param name="message">The message to send</param>
        /// <param name="recipient">The recipient connection</param>
        /// <param name="method">How to deliver the message</param>
        /// <param name="sequenceChannel">Sequence channel within the delivery method</param>
        public NetSendResult SendMessage(
            NetOutgoingMessage message, NetConnection recipient, NetDeliveryMethod method, int sequenceChannel)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }
            if (recipient == null)
            {
                throw new ArgumentNullException(nameof(recipient));
            }

            NetConstants.AssertValidDeliveryChannel(
                method, sequenceChannel, nameof(method), nameof(sequenceChannel));

            message.AssertNotSent(nameof(message));
            message._isSent = true;

            bool suppressFragmentation =
                (method == NetDeliveryMethod.Unreliable || method == NetDeliveryMethod.UnreliableSequenced) &&
                Configuration.UnreliableSizeBehaviour != NetUnreliableSizeBehaviour.NormalFragmentation;

            if (suppressFragmentation || message.GetEncodedSize() <= recipient.CurrentMTU)
            {
                Interlocked.Increment(ref message._recyclingCount);
                return(recipient.EnqueueMessage(message, method, sequenceChannel).Result);
            }
            else
            {
                // message must be fragmented!
                if (recipient.Status != NetConnectionStatus.Connected)
                {
                    return(NetSendResult.FailedNotConnected);
                }

                List <NetConnection> recipients = NetConnectionListPool.Rent(1);
                try
                {
                    recipients.Add(recipient);
                    return(SendFragmentedMessage(message, recipients, method, sequenceChannel));
                }
                finally
                {
                    NetConnectionListPool.Return(recipients);
                }
            }
        }
Beispiel #23
0
        public void BroadcastPacket(NetOutgoingMessage msg, NetDeliveryMethod deliveryMethod)
        {
            if (radioClients.Count == 0)
            {
                return;
            }

            try
            {
                HubListener.ListenerServer.SendMessage(msg, radioClients.Select(x => x.playerConnection).ToList(), deliveryMethod, (deliveryMethod == NetDeliveryMethod.UnreliableSequenced ? 1 : 0));
                Program.networkBytesOutNow += msg.LengthBytes * radioClients.Count;
            }
            catch (Exception e)
            {
                Logger.Instance.Warning($"Unable to send packet to players! Exception: {e}");
            }
        }
        public NetUnreliableSenderChannel(NetConnection connection, int windowSize, NetDeliveryMethod method)
        {
            LidgrenException.AssertIsPowerOfTwo((ulong)windowSize, nameof(windowSize));

            _connection   = connection;
            _windowSize   = windowSize;
            _windowStart  = 0;
            _sendStart    = 0;
            _receivedAcks = new NetBitArray(NetConstants.SequenceNumbers);

            _doFlowControl = true;
            if (method == NetDeliveryMethod.Unreliable &&
                connection.Peer.Configuration.SuppressUnreliableUnorderedAcks)
            {
                _doFlowControl = false;
            }
        }
Beispiel #25
0
        public static DeliveryMethod ToDeliveryMethod(this NetDeliveryMethod value)
        {
            switch (value)
            {
            case NetDeliveryMethod.ReliableOrdered:
                return(DeliveryMethod.Reliable);

            case NetDeliveryMethod.Unreliable:
                return(DeliveryMethod.Unreliable);

            case NetDeliveryMethod.UnreliableSequenced:
                return(DeliveryMethod.UnreliableOrdered);

            default:
                return(DeliveryMethod.Unknown);
            }
        }
        /// <summary>
        /// Sends a message to the relevant system(s) serverside.
        /// </summary>
        public void SendSystemNetworkMessage(EntitySystemMessage message,
                                             NetDeliveryMethod method = NetDeliveryMethod.ReliableUnordered)
        {
            NetOutgoingMessage newMsg = CreateEntityMessage();

            newMsg.Write((byte)EntityMessage.SystemMessage);

            using (var stream = new MemoryStream())
            {
                serializer.Serialize(stream, message);
                newMsg.Write((int)stream.Length);
                newMsg.Write(stream.ToArray());
            }

            //Send the message
            _networkManager.ClientSendMessage(newMsg, method);
        }
Beispiel #27
0
        /// <summary>
        /// Sends a message to the counterpart component on the server side
        /// </summary>
        /// <param name="component">Sending component</param>
        /// <param name="method">Net Delivery Method</param>
        /// <param name="recipient">The intended recipient netconnection (if null send to all)</param>
        /// <param name="messageParams">Parameters</param>
        public void SendDirectedComponentNetworkMessage(IComponent component, NetDeliveryMethod method,
                                                        NetConnection recipient, params object[] messageParams)
        {
            if (component.NetID == null)
            {
                throw new ArgumentException("Component has no Net ID and cannot be used across the network.");
            }

            if (!Initialized)
            {
                return;
            }

            EntityNetworkManager.SendDirectedComponentNetworkMessage(this, component.NetID.Value,
                                                                     method, recipient,
                                                                     messageParams);
        }
Beispiel #28
0
        public virtual void BroadcastPacket(NetOutgoingMessage msg, NetDeliveryMethod deliveryMethod, int seqChannel, List <Client> excludeClients = null)
        {
            if (roomClients.Count == 0 || roomClients.Count(x => excludeClients == null || !excludeClients.Contains(x)) == 0)
            {
                return;
            }

            try
            {
                HubListener.ListenerServer.SendMessage(msg, roomClients.Where(x => excludeClients == null || !excludeClients.Contains(x)).Select(x => x.playerConnection).ToList(), deliveryMethod, seqChannel);
                Program.networkBytesOutNow += msg.LengthBytes * roomClients.Where(x => excludeClients == null || !excludeClients.Contains(x)).Count();
            }
            catch (Exception e)
            {
                Logger.Instance.Warning($"Unable to send packet to players! Exception: {e}");
            }
        }
Beispiel #29
0
        public override void Send(IWriteMessage msg, DeliveryMethod deliveryMethod)
        {
            if (!isActive)
            {
                return;
            }

            NetDeliveryMethod lidgrenDeliveryMethod = NetDeliveryMethod.Unreliable;

            switch (deliveryMethod)
            {
            case DeliveryMethod.Unreliable:
                lidgrenDeliveryMethod = NetDeliveryMethod.Unreliable;
                break;

            case DeliveryMethod.Reliable:
                lidgrenDeliveryMethod = NetDeliveryMethod.ReliableUnordered;
                break;

            case DeliveryMethod.ReliableOrdered:
                lidgrenDeliveryMethod = NetDeliveryMethod.ReliableOrdered;
                break;
            }

            NetOutgoingMessage lidgrenMsg = netClient.CreateMessage();

            byte[] msgData = new byte[msg.LengthBytes];
            msg.PrepareForSending(ref msgData, out bool isCompressed, out int length);
            lidgrenMsg.Write(selfSteamID);
            lidgrenMsg.Write((byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None));
            lidgrenMsg.Write((UInt16)length);
            lidgrenMsg.Write(msgData, 0, length);

#if DEBUG
            netPeerConfiguration.SimulatedDuplicatesChance = GameMain.Client.SimulatedDuplicatesChance;
            netPeerConfiguration.SimulatedMinimumLatency   = GameMain.Client.SimulatedMinimumLatency;
            netPeerConfiguration.SimulatedRandomLatency    = GameMain.Client.SimulatedRandomLatency;
            netPeerConfiguration.SimulatedLoss             = GameMain.Client.SimulatedLoss;
#endif
            NetSendResult result = netClient.SendMessage(lidgrenMsg, lidgrenDeliveryMethod);
            if (result != NetSendResult.Queued && result != NetSendResult.Sent)
            {
                DebugConsole.NewMessage("Failed to send own message to host: " + result);
            }
        }
Beispiel #30
0
        public void SendMessage(PacketDeliveryMethod method, INetworkPacket packet, string accountName)
        {
            if (!_usernameToConnection.ContainsKey(accountName))
            {
                return;
            }
            NetConnection recipient = _usernameToConnection[accountName];

            NetOutgoingMessage message = _server.CreateMessage();
            MemoryStream       stream  = new MemoryStream();

            Serializer.Serialize(stream, packet);
            message.Write(stream.ToArray());

            // This may seem redundant but I am protecting against the possibility that
            // Lidgren is vaporware. Should we need to swap out the network code in the future,
            // only this class will need to be touched.
            NetDeliveryMethod deliveryMethod = NetDeliveryMethod.Unreliable;

            switch (method)
            {
            case PacketDeliveryMethod.Unreliable:
                deliveryMethod = NetDeliveryMethod.Unreliable;
                break;

            case PacketDeliveryMethod.UnreliableSequenced:
                deliveryMethod = NetDeliveryMethod.UnreliableSequenced;
                break;

            case PacketDeliveryMethod.ReliableUnordered:
                deliveryMethod = NetDeliveryMethod.ReliableUnordered;
                break;

            case PacketDeliveryMethod.ReliableSequenced:
                deliveryMethod = NetDeliveryMethod.ReliableSequenced;
                break;

            case PacketDeliveryMethod.ReliableOrdered:
                deliveryMethod = NetDeliveryMethod.ReliableOrdered;
                break;
            }


            _server.SendMessage(message, recipient, deliveryMethod);
        }
Beispiel #31
0
        public NetSendResult Send <T>(ref T evnt, NetConnection connection, NetDeliveryMethod deliveryMethod, int sequenceChannel, int maxSize = DEFAULT_MAX_SIZE)
            where T : struct, IMyEvent
        {
            NetOutgoingMessage  msg;
            MyRelayedConnection relayedConnection = connection as MyRelayedConnection;

            if (relayedConnection != null)
            {
                if (RelayServerConnection == null)
                {
                    //RaisePeerDisconnected(connection);
                    return(NetSendResult.FailedNotConnected);
                }

                maxSize += sizeof(byte); // Event type enum
                maxSize += 16;           // 16B for IPv6 addr
                maxSize += sizeof(int);  // Port

                msg = CreateMessage(maxSize);

                // Write relay header
                msg.Write((byte)MyEventEnum.RELAY);
                msg.Write(relayedConnection.RelayTargetEp);

                connection = RelayServerConnection;
            }
            else
            {
                msg = CreateMessage(maxSize);
            }

            Write(msg, evnt);
            if (CanEnqueue(connection.Status))
            {
                m_messageQueue.Add(new MyMessageQueueItem()
                {
                    Message = msg, DeliveryMethod = deliveryMethod, SequenceChannel = sequenceChannel, EndPoint = connection.RemoteEndpoint
                });
                return(NetSendResult.Queued);
            }
            else
            {
                return(connection.SendMessage(msg, deliveryMethod, sequenceChannel));
            }
        }
        /// <summary>
        /// Sends a message to the relevant system(s) on the target client.
        /// </summary>
        public void SendSystemNetworkMessage(EntitySystemMessage message,
                                             INetChannel targetConnection = null,
                                             NetDeliveryMethod method     = NetDeliveryMethod.ReliableUnordered)
        {
            MsgEntity newMsg = _mNetManager.CreateNetMessage <MsgEntity>();

            newMsg.Type          = EntityMessage.SystemMessage;
            newMsg.SystemMessage = message;

            //Send the message
            if (targetConnection != null)
            {
                _mNetManager.ServerSendMessage(newMsg, targetConnection);
            }
            else
            {
                _mNetManager.ServerSendToAll(newMsg);
            }
        }
        /* Documentation on Delivery Methods
         * Unreliable              This is just UDP. Messages can be lost or received more than once.
         *                      Messages may not be received in the same order as they were sent.
         *
         * UnreliableSequenced     Using this delivery method messages can still be lost; but you're protected against duplicated messages.
         *                      If a message arrives late; that is, if a message sent after this one has already been received - it will be dropped.
         *                      This means you will never receive "older" data than what you already have received.
         *
         * ReliableUnordered       This delivery method ensures that every message sent will be eventually received.
         *                      It does not however guarantee what order they will be received in; late messages may be delivered before newer ones.
         *
         * ReliableSequenced       This delivery method is similar to UnreliableSequenced; except that it guarantees that SOME messages will be received
         *                      - if you only send one message - it will be received.
         *                      If you sent two messages quickly, and they get reordered in transit, only the newest message will be received
         *                      - but at least ONE of them will be received.
         *
         * ReliableOrdered         This delivery method guarantees that messages will always be received in the exact order they were sent.
         */

        public static void DetermineMethodandChannel(ClientMessageType messageType, out NetDeliveryMethod deliverymethod, out int?sequenceChannel)
        {
            //Determine the delivery type and if needed, the sequence channel
            sequenceChannel = null;

            switch (messageType)
            {
            case ClientMessageType.Beat:
                throw new Exception("Shouldn't be sending beats this way (Specific beat function that recycles message)");

            case ClientMessageType.SendName:
                deliverymethod  = NetDeliveryMethod.ReliableOrdered;
                sequenceChannel = 0;
                break;

            default:
                throw new Exception("Could not determine datatype");
            }
        }
        public bool SendPacketToAllExcept(Packet packet, Guid playerId, ChannelType channelType = ChannelType.ReliableOrdered)
        {
#if DEBUG
            Console.WriteLine($"Send - Type: {packet.GetType().Name}");
#endif
            if (!playerConnections.ContainsKey(playerId))
            {
                Console.WriteLine("Failed to send packet to players: Excluded player not found.");
                return(false);
            }

            long excludedId = playerConnections[playerId];

            NetOutgoingMessage msg = server.CreateMessage();
            msg.Write(packet.Serialize());
            NetDeliveryMethod deliveryMethod = ChannelTypeUtils.ChannelTypeToLidgren(channelType);
            server.SendToAll(msg, server.Connections.First(p => p.RemoteUniqueIdentifier == excludedId), deliveryMethod, 1);
            return(true);
        }
Beispiel #35
0
        private bool Dispatch(Peer toPassTo, IPackage packet, NetDeliveryMethod method)
        {
            try
            {
                //TODO: Refactor
                switch ((Packet.OperationType)packet.OperationType)
                {
                case Packet.OperationType.Event:
                    EventPackage ePackage = GeneratePackage <EventPackage>(packet);
                    if (ePackage != null)
                    {
                        toPassTo.PackageRecieve(ePackage, new MessageInfo(method));
                    }
                    return(true);

                case Packet.OperationType.Request:
                    //ClassLogger.LogDebug("Hit request");
                    RequestPackage rqPackage = GeneratePackage <RequestPackage>(packet);
                    if (rqPackage != null)
                    {
                        //ClassLogger.LogDebug("About to call peer method");
                        toPassTo.PackageRecieve(rqPackage, new MessageInfo(method));
                    }
                    return(true);

                case Packet.OperationType.Response:
                    ResponsePackage rPackage = GeneratePackage <ResponsePackage>(packet);
                    if (rPackage != null)
                    {
                        toPassTo.PackageRecieve(rPackage, new MessageInfo(method));
                    }
                    return(true);

                default:
                    return(false);
                }
            }
            catch (LoggableException e)
            {
                ClassLogger.LogError(e.Message + e.InnerException != null ? " Inner: " + e.InnerException : "");
                return(false);
            }
        }
        bool CallFunc(string functionName, NetConnection onConnection, RemoteFunctionCallback callback,
                      RemoteFlag flags, NetDeliveryMethod deliveryMethod, NetBuffer data, ushort numArgs)
        {
            // Allocate Id
            ushort callbackId = GetNextCallbackId();

            // Create the function packet
            NetOutboundPacket funcPacket = new NetOutboundPacket(deliveryMethod);

            funcPacket.Type = NetPacketType.RemoteFunction;

            // Handle the flags
            funcPacket.Encrypt = flags.HasFlag(RemoteFlag.Encrypt);
            if (flags.HasFlag(RemoteFlag.DontCompress))
            {
                funcPacket.Compression = NetPacketCompression.None;
            }
            funcPacket.SendImmediately = flags.HasFlag(RemoteFlag.SendImmediately);

            // Write the function header
            funcPacket.Write((byte)Type);
            funcPacket.Write(Id);
            funcPacket.Write(functionName);
            funcPacket.Write(callbackId);
            funcPacket.Write(numArgs);

            // Write the data for the function
            funcPacket.WriteBytes(data.data, 0, data.Length);

            // Add the waiting function for the return value callback
            if (WaitingFunctions.TryAdd(callbackId, callback))
            {
                // Send the event packet
                onConnection.SendPacket(funcPacket);
                return(true);
            }
            else
            {
                NetLogger.LogError("Failed to call function {0}, this function is already in the middle of being called!",
                                   functionName);
                return(false);
            }
        }
Beispiel #37
0
        public void SendMessage(PacketDeliveryMethod method, INetworkPacket packet)
        {
            if (_serverConnection == null ||
                _serverConnection.Status != NetConnectionStatus.Connected)
            {
                throw new Exception("Client is not currently connected to a server.");
            }

            NetOutgoingMessage message = _client.CreateMessage();
            MemoryStream       stream  = new MemoryStream();

            Serializer.Serialize(stream, packet);
            message.Write(stream.ToArray());

            // This may seem redundant but I am protecting against the possibility that
            // Lidgren is vaporware. Should we need to swap out the network code in the future,
            // only this class will need to be touched.
            NetDeliveryMethod deliveryMethod = NetDeliveryMethod.Unreliable;

            switch (method)
            {
            case PacketDeliveryMethod.Unreliable:
                deliveryMethod = NetDeliveryMethod.Unreliable;
                break;

            case PacketDeliveryMethod.UnreliableSequenced:
                deliveryMethod = NetDeliveryMethod.UnreliableSequenced;
                break;

            case PacketDeliveryMethod.ReliableUnordered:
                deliveryMethod = NetDeliveryMethod.ReliableUnordered;
                break;

            case PacketDeliveryMethod.ReliableSequenced:
                deliveryMethod = NetDeliveryMethod.ReliableSequenced;
                break;

            case PacketDeliveryMethod.ReliableOrdered:
                deliveryMethod = NetDeliveryMethod.ReliableOrdered;
                break;
            }
            _client.SendMessage(message, deliveryMethod);
        }
        /// <summary>
        /// Sends a message to the relevant system(s) serverside.
        /// </summary>
        public void SendSystemNetworkMessage(EntitySystemMessage message,
                                             NetDeliveryMethod method = NetDeliveryMethod.ReliableUnordered)
        {
            NetOutgoingMessage newMsg = CreateEntityMessage();
            newMsg.Write((byte)EntityMessage.SystemMessage);

            var stream = new MemoryStream();
            Serializer.Serialize(stream, message);
            newMsg.Write((int)stream.Length);
            newMsg.Write(stream.ToArray());

            if (_messageProfiling)
            {
                //Log the message
            }

            //Send the message
            _networkManager.SendMessage(newMsg, method);
        }
Beispiel #39
0
        private NetReceiverChannelBase CreateReceiverChannel(NetMessageType tp)
        {
            m_peer.VerifyNetworkThread();

            // create receiver channel
            NetReceiverChannelBase chan;
            NetDeliveryMethod      method = NetUtility.GetDeliveryMethod(tp);

            switch (method)
            {
            case NetDeliveryMethod.Unreliable:
                chan = new NetUnreliableUnorderedReceiver(this);
                break;

            case NetDeliveryMethod.ReliableOrdered:
                chan = new NetReliableOrderedReceiver(this, NetConstants.ReliableOrderedWindowSize);
                break;

            case NetDeliveryMethod.UnreliableSequenced:
                chan = new NetUnreliableSequencedReceiver(this);
                break;

            case NetDeliveryMethod.ReliableUnordered:
                chan = new NetReliableUnorderedReceiver(this, NetConstants.ReliableOrderedWindowSize);
                break;

            case NetDeliveryMethod.ReliableSequenced:
                chan = new NetReliableSequencedReceiver(this, NetConstants.ReliableSequencedWindowSize);
                break;

            case NetDeliveryMethod.Unknown:
            default:
                throw new NetException("Unhandled NetDeliveryMethod!");
            }

            int channelSlot = (int)tp - 1;

            NetException.Assert(m_receiveChannels[channelSlot] == null);
            m_receiveChannels[channelSlot] = chan;

            return(chan);
        }
        /// <summary>
        /// Allows a component owned by this entity to send a message to a counterpart component on the
        /// counterpart entities on all clients.
        /// </summary>
        /// <param name="sendingEntity">Entity sending the message (also entity to send to)</param>   
        /// <param name="family">Family of the component sending the message</param>
        /// <param name="method">Net delivery method -- if null, defaults to NetDeliveryMethod.ReliableUnordered</param>
        /// <param name="messageParams">Parameters of the message</param>
        public void SendComponentNetworkMessage(Entity sendingEntity, ComponentFamily family,
                                                NetDeliveryMethod method = NetDeliveryMethod.ReliableUnordered,
                                                params object[] messageParams)
        {
            NetOutgoingMessage message = CreateEntityMessage();
            message.Write((byte)EntityMessage.ComponentMessage);
            message.Write(sendingEntity.Uid); //Write this entity's UID
            message.Write((byte) family);
            PackParams(message, messageParams);

            if (_messageProfiling)
            {
//Log the message
                var logger = IoCManager.Resolve<IMessageLogger>();
                logger.LogOutgoingComponentNetMessage(sendingEntity.Uid, family, messageParams);
            }

            //Send the message
            _networkManager.SendMessage(message, method);
        }
Beispiel #41
0
        /// <summary>
        /// Gets the window size used internally in the library for a certain delivery method
        /// </summary>
        public static int GetWindowSize(NetDeliveryMethod method)
        {
            switch (method)
            {
            case NetDeliveryMethod.Unknown:
                return(0);

            case NetDeliveryMethod.Unreliable:
            case NetDeliveryMethod.UnreliableSequenced:
                return(NetConstants.UnreliableWindowSize);

            case NetDeliveryMethod.ReliableOrdered:
                return(NetConstants.ReliableOrderedWindowSize);

            case NetDeliveryMethod.ReliableSequenced:
            case NetDeliveryMethod.ReliableUnordered:
            default:
                return(NetConstants.DefaultWindowSize);
            }
        }
Beispiel #42
0
        // may be on user thread
        private NetSenderChannelBase CreateSenderChannel(NetMessageType tp)
        {
            NetSenderChannelBase chan;

            lock (m_sendChannels)
            {
                NetDeliveryMethod method = NetUtility.GetDeliveryMethod(tp);
                int sequenceChannel      = (int)tp - (int)method;

                int channelSlot = (int)method - 1 + sequenceChannel;
                if (m_sendChannels[channelSlot] != null)
                {
                    // we were pre-empted by another call to this method
                    chan = m_sendChannels[channelSlot];
                }
                else
                {
                    switch (method)
                    {
                    case NetDeliveryMethod.Unreliable:
                    case NetDeliveryMethod.UnreliableSequenced:
                        chan = new NetUnreliableSenderChannel(this, NetUtility.GetWindowSize(method), method);
                        break;

                    case NetDeliveryMethod.ReliableOrdered:
                        chan = new NetReliableSenderChannel(this, NetUtility.GetWindowSize(method));
                        break;

                    case NetDeliveryMethod.Unknown:
                    case NetDeliveryMethod.ReliableSequenced:
                    case NetDeliveryMethod.ReliableUnordered:
                    default:
                        chan = new NetReliableSenderChannel(this, NetUtility.GetWindowSize(method));
                        break;
                    }
                    m_sendChannels[channelSlot] = chan;
                }
            }

            return(chan);
        }
        /// <summary>
        /// Allows a component owned by this entity to send a message to a counterpart component on the
        /// counterpart entities on all clients.
        /// </summary>
        /// <param name="sendingEntity">Entity sending the message (also entity to send to)</param>
        /// <param name="family">Family of the component sending the message</param>
        /// <param name="method">Net delivery method -- if null, defaults to NetDeliveryMethod.ReliableUnordered</param>
        /// <param name="recipient">Client connection to send to. If null, send to all.</param>
        /// <param name="messageParams">Parameters of the message</param>
        public void SendDirectedComponentNetworkMessage(IEntity sendingEntity, uint netID,
                                                        NetDeliveryMethod method,
                                                        INetChannel recipient, params object[] messageParams)
        {
            MsgEntity message = _mNetManager.CreateNetMessage <MsgEntity>();

            message.Type       = EntityMessage.ComponentMessage;
            message.EntityId   = sendingEntity.Uid;
            message.NetId      = netID;
            message.Parameters = new List <object>(messageParams);

            //Send the message
            if (recipient == null)
            {
                _mNetManager.ServerSendToAll(message);
            }
            else
            {
                _mNetManager.ServerSendMessage(message, recipient);
            }
        }
Beispiel #44
0
        /// <summary>
        /// TODO: Add caching.
        /// </summary>
        /// <returns></returns>
        protected int GetMessageSequenceChannel(int messageType, NetDeliveryMethod deliveryMethod)
        {
            /// MAX: 31
            //  https://github.com/lidgren/lidgren-network-gen3/wiki/Sequence-Channels
            int sequenceChannel = 0;

            switch (deliveryMethod)
            {
            case NetDeliveryMethod.ReliableUnordered:
            case NetDeliveryMethod.Unreliable:
                // if it's unreliable or unordered, then they may share a sequence channel, as sequence doesn't matter.
                sequenceChannel = 0;
                break;

            default:
                // in all other cases, sequence matters, so we must use a separate channel per message type.
                sequenceChannel = messageType;
                break;
            }
            return(sequenceChannel);
        }
Beispiel #45
0
        /// <summary>
        /// Allows a component owned by this entity to send a message to a counterpart component on the
        /// counterpart entities on all clients.
        /// </summary>
        /// <param name="sendingEntity">Entity sending the message (also entity to send to)</param>
        /// <param name="family">Family of the component sending the message</param>
        /// <param name="method">Net delivery method -- if null, defaults to NetDeliveryMethod.ReliableUnordered</param>
        /// <param name="messageParams">Parameters of the message</param>
        public void SendComponentNetworkMessage(Entity sendingEntity, ComponentFamily family,
                                                NetDeliveryMethod method = NetDeliveryMethod.ReliableUnordered,
                                                params object[] messageParams)
        {
            NetOutgoingMessage message = CreateEntityMessage();

            message.Write((byte)EntityMessage.ComponentMessage);
            message.Write(sendingEntity.Uid); //Write this entity's UID
            message.Write((byte)family);
            PackParams(message, messageParams);

            if (_messageProfiling)
            {
//Log the message
                var logger = IoCManager.Resolve <IMessageLogger>();
                logger.LogOutgoingComponentNetMessage(sendingEntity.Uid, family, messageParams);
            }

            //Send the message
            _networkManager.SendMessage(message, method);
        }
Beispiel #46
0
        public void SendToAllExceptOneClient(ushort exceptThisClient, Message msg, NetDeliveryMethod deliveryType)
        {
            /*
             * NetOutgoingMessage msgOut = netServer.CreateMessage();
             *
             * msgOut.Write(Message.GetMessageCode(msg.GetType()));
             * msg.Write(msgOut);
             *
             * foreach(ushort clid in activeClients)
             * {
             *  if(clid != exceptThisClient)
             *      netServer.SendMessage(msgOut, clientInfo[clid].connection, deliveryType);
             * }
             */
            NetOutgoingMessage msgOut = netServer.CreateMessage();

            msgOut.Write(Message.GetMessageCode(msg.GetType()));
            msg.Write(msgOut);

            netServer.SendToAll(msgOut, clientInfo[exceptThisClient].connection, deliveryType, 0);
        }
Beispiel #47
0
        public void SendMessage(Message message, NetDeliveryMethod deliveryMethod, int sequenceChannel)
        {
            var outgoingMessage = netPeer.CreateMessage();

            message.WritePayload(outgoingMessage);

            if (Key != null)
            {
                IsAuthenticated = true;
                //outgoingMessage.Encrypt(cryptoAlgorithm);
            }

            netPeer.SendMessage(outgoingMessage, Connections, deliveryMethod, sequenceChannel);

            //Trace.WriteLine("Sent " + ((CustomMessageType)message.MessageType).ToString() + ".");

            if (OnConnectedMessageSent != null)
            {
                OnConnectedMessageSent(this, new MessageEventArgs(this, message));
            }
        }
Beispiel #48
0
        /// <summary>
        /// Send a message to a specific connection
        /// </summary>
        /// <param name="msg">The message to send</param>
        /// <param name="recipient">The recipient connection</param>
        /// <param name="method">How to deliver the message</param>
        /// <param name="sequenceChannel">Sequence channel within the delivery method</param>
        public NetSendResult SendMessage(INetOutgoingMessage msg, INetConnection recipient, NetDeliveryMethod method, int sequenceChannel)
        {
            NetOutgoingMessage _msg = (NetOutgoingMessage)msg;
            NetConnection _recipient = (NetConnection)recipient;
            if (msg == null)
                throw new ArgumentNullException("msg");
            if (recipient == null)
                throw new ArgumentNullException("recipient");
            if (sequenceChannel >= NetConstants.NetChannelsPerDeliveryMethod)
                throw new ArgumentOutOfRangeException("sequenceChannel");

            NetException.Assert(
                ((method != NetDeliveryMethod.Unreliable && method != NetDeliveryMethod.ReliableUnordered) ||
                ((method == NetDeliveryMethod.Unreliable || method == NetDeliveryMethod.ReliableUnordered) && sequenceChannel == 0)),
                "Delivery method " + method + " cannot use sequence channels other than 0!"
            );

            NetException.Assert(method != NetDeliveryMethod.Unknown, "Bad delivery method!");

            if (_msg.m_isSent)
                throw new NetException("This message has already been sent! Use NetPeer.SendMessage() to send to multiple recipients efficiently");
            _msg.m_isSent = true;

            bool suppressFragmentation = (method == NetDeliveryMethod.Unreliable || method == NetDeliveryMethod.UnreliableSequenced) && m_configuration.UnreliableSizeBehaviour != NetUnreliableSizeBehaviour.NormalFragmentation;

            int len = NetConstants.UnfragmentedMessageHeaderSize + msg.LengthBytes; // headers + length, faster than calling msg.GetEncodedSize
            if (len <= _recipient.m_currentMTU || suppressFragmentation)
            {
                Interlocked.Increment(ref _msg.m_recyclingCount);
                return _recipient.EnqueueMessage(_msg, method, sequenceChannel);
            }
            else
            {
                // message must be fragmented!
                if (_recipient.m_status != NetConnectionStatus.Connected)
                    return NetSendResult.FailedNotConnected;
                return SendFragmentedMessage(_msg, new NetConnection[] { _recipient }, method, sequenceChannel);
            }
        }
Beispiel #49
0
        /// <summary>
        /// Send a message to all connections except one
        /// </summary>
        /// <param name="msg">The message to send</param>
        /// <param name="method">How to deliver the message</param>
        /// <param name="except">Don't send to this particular connection</param>
        /// <param name="sequenceChannel">Which sequence channel to use for the message</param>
        public void SendToAll(NetOutgoingMessage msg, INetConnection except, NetDeliveryMethod method, int sequenceChannel)
        {
            var all = this.Connections;
            if (all.Count <= 0) {
                if (msg.m_isSent == false)
                    Recycle(msg);
                return;
            }

            if (except == null)
            {
                SendMessage(msg, all, method, sequenceChannel);
                return;
            }

            List<INetConnection> recipients = new List<INetConnection>(all.Count - 1);
            foreach (var conn in all)
                if (conn != except)
                    recipients.Add(conn);

            if (recipients.Count > 0)
                SendMessage(msg, recipients, method, sequenceChannel);
        }
Beispiel #50
0
		/// <summary>
		/// Zero windowSize indicates that the channel is not yet instantiated (used)
		/// Negative freeWindowSlots means this amount of messages are currently queued but delayed due to closed window
		/// </summary>
		public void GetSendQueueInfo(NetDeliveryMethod method, int sequenceChannel, out int windowSize, out int freeWindowSlots)
		{
			int channelSlot = (int)method - 1 + sequenceChannel;
			var chan = m_sendChannels[channelSlot];
			if (chan == null)
			{
				windowSize = NetUtility.GetWindowSize(method);
				freeWindowSlots = windowSize;
				return;
			}

			windowSize = chan.WindowSize;
			freeWindowSlots = chan.GetAllowedSends() - chan.m_queuedSends.Count;
			return;
		}
Beispiel #51
0
		// called by SendMessage() and NetPeer.SendMessage; ie. may be user thread
		internal NetSendResult EnqueueMessage(NetOutgoingMessage msg, NetDeliveryMethod method, int sequenceChannel)
		{
			if (m_status != NetConnectionStatus.Connected)
				return NetSendResult.FailedNotConnected;

			NetMessageType tp = (NetMessageType)((int)method + sequenceChannel);
			msg.m_messageType = tp;

			// TODO: do we need to make this more thread safe?
			int channelSlot = (int)method - 1 + sequenceChannel;
			NetSenderChannelBase chan = m_sendChannels[channelSlot];
			if (chan == null)
				chan = CreateSenderChannel(tp);

			if (msg.GetEncodedSize() > m_currentMTU)
				throw new NetException("Message too large! Fragmentation failure?");

			var retval = chan.Enqueue(msg);
			if (retval == NetSendResult.Sent && m_peerConfiguration.m_autoFlushSendQueue == false)
				retval = NetSendResult.Queued; // queued since we're not autoflushing
			return retval;
		}
Beispiel #52
0
		/// <summary>
		/// Send a message to this remote connection
		/// </summary>
		/// <param name="msg">The message to send</param>
		/// <param name="method">How to deliver the message</param>
		/// <param name="sequenceChannel">Sequence channel within the delivery method</param>
		public NetSendResult SendMessage(NetOutgoingMessage msg, NetDeliveryMethod method, int sequenceChannel)
		{
			return m_peer.SendMessage(msg, this, method, sequenceChannel);
		}
 public void SendMessageToAllClients(NetOutgoingMessage mes,NetDeliveryMethod method = NetDeliveryMethod.Unreliable)
 {
     server.SendMessage(mes, server.Connections, method,0);
 }
 /// <summary>
 /// Send a message to a specific connection
 /// </summary>
 /// <param name="msg">The message to send</param>
 /// <param name="recipient">The recipient connection</param>
 /// <param name="method">How to deliver the message</param>
 public NetSendResult SendMessage(NetOutgoingMessage msg, NetConnection recipient, NetDeliveryMethod method)
 {
     return SendMessage(msg, recipient, method, 0);
 }
        /// <summary>
        /// Sends data to the other end of the connection.
        /// </summary>
        /// <param name="data">Data to send.</param>
        /// <param name="deliveryMethod">The method to use to deliver the message. This determines how reliability, ordering,
        /// and sequencing will be handled.</param>
        /// <param name="sequenceChannel">The sequence channel to use to deliver the message. Only valid when
        /// <paramref name="deliveryMethod"/> is not equal to <see cref="NetDeliveryMethod.Unreliable"/> or
        /// <see cref="NetDeliveryMethod.ReliableUnordered"/>. Must also be a value between 0 and
        /// <see cref="NetConstants.NetChannelsPerDeliveryMethod"/>.</param>
        /// <returns>
        /// True if the <paramref name="data"/> was successfully enqueued for sending; otherwise false.
        /// </returns>
        /// <exception cref="NetException"><paramref name="deliveryMethod"/> equals <see cref="NetDeliveryMethod.Unreliable"/>
        /// or <see cref="NetDeliveryMethod.ReliableUnordered"/> and <paramref name="sequenceChannel"/> is non-zero.</exception>
        /// <exception cref="NetException"><paramref name="sequenceChannel"/> is less than 0 or greater than
        /// <see cref="NetConstants.NetChannelsPerDeliveryMethod"/>.</exception>
        /// <exception cref="NetException"><paramref name="deliveryMethod"/> equals <see cref="NetDeliveryMethod.Unknown"/>.</exception>
        public bool Send(byte[] data, NetDeliveryMethod deliveryMethod, int sequenceChannel = 0)
        {
            var sock = RemoteSocket;
            if (sock == null)
            {
                const string errmsg = "Could not send data - connection not established!";
                if (log.IsErrorEnabled)
                    log.Error(errmsg);
                Debug.Fail(errmsg);
                return false;
            }

            try
            {
                var ret = sock.Send(data, deliveryMethod, sequenceChannel);
                if (!ret)
                    Debug.Fail("Sending to server failed.");
                return ret;
            }
            catch (Exception ex)
            {
                const string errmsg = "Failed to send data. Exception: {0}";
                if (log.IsErrorEnabled)
                    log.ErrorFormat(errmsg, ex);
                Debug.Fail(string.Format(errmsg, ex));
                return false;
            }
        }
Beispiel #56
0
		/// <summary>
		/// Sends message to server
		/// </summary>
		public NetSendResult SendMessage(NetOutgoingMessage msg, NetDeliveryMethod method, int sequenceChannel)
		{
			NetConnection serverConnection = ServerConnection;
			if (serverConnection == null)
			{
				LogWarning("Cannot send message, no server connection!");
				return NetSendResult.Failed;
			}

			return serverConnection.SendMessage(msg, method, sequenceChannel);
		}
Beispiel #57
0
 public NetSendResult SendMessage(NetOutgoingMessage msg, NetDeliveryMethod method)
 {
     return gameKeeper.Server.SendMessage(msg, Connection, method);
 }
Beispiel #58
0
 /// <summary>
 /// Send a message to all connections
 /// </summary>
 /// <param name="msg">The message to send</param>
 /// <param name="method">How to deliver the message</param>
 public void SendToAll(NetOutgoingMessage msg, NetDeliveryMethod method)
 {
     SendMessage(msg, this.Connections, method, 0);
 }
 public void SendMessage(NetOutgoingMessage message, NetDeliveryMethod deliveryMethod)
 {
     if (message != null)
     {
         NetClient.SendMessage(message, deliveryMethod);
     }
 }
Beispiel #60
0
 public NetSendResult SendMessage(NetOutgoingMessage msg, NetDeliveryMethod method, int sequenceChannel)
 {
     return gameKeeper.Server.SendMessage(msg, Connection, method, sequenceChannel);
 }