public void SendToClients(List <Client> clients)
        {
            foreach (VoipQueue queue in queues)
            {
                if (queue.LastReadTime < DateTime.Now - VoipConfig.SEND_INTERVAL)
                {
                    continue;
                }

                if (lastSendTime.ContainsKey(queue))
                {
                    if ((lastSendTime[queue] + VoipConfig.SEND_INTERVAL) > DateTime.Now)
                    {
                        continue;
                    }
                    lastSendTime[queue] = DateTime.Now;
                }
                else
                {
                    lastSendTime.Add(queue, DateTime.Now);
                }

                Client sender = clients.Find(c => c.VoipQueue == queue);

                foreach (Client recipient in clients)
                {
                    if (recipient == sender)
                    {
                        continue;
                    }

                    if (!CanReceive(sender, recipient))
                    {
                        continue;
                    }

                    IWriteMessage msg = new WriteOnlyMessage();

                    msg.Write((byte)ServerPacketHeader.VOICE);
                    msg.Write((byte)queue.QueueID);
                    queue.Write(msg);

                    netServer.Send(msg, recipient.Connection, DeliveryMethod.Unreliable);
                }
            }
        }
Exemple #2
0
        public void Update(float deltaTime)
        {
            activeTransfers.RemoveAll(t => t.Connection.Status != NetworkConnectionStatus.Connected);

            var endedTransfers = activeTransfers.FindAll(t =>
                                                         t.Connection.Status != NetworkConnectionStatus.Connected ||
                                                         t.Status == FileTransferStatus.Finished ||
                                                         t.Status == FileTransferStatus.Canceled ||
                                                         t.Status == FileTransferStatus.Error);

            foreach (FileTransferOut transfer in endedTransfers)
            {
                activeTransfers.Remove(transfer);
                OnEnded(transfer);
            }

            foreach (FileTransferOut transfer in activeTransfers)
            {
                transfer.WaitTimer -= deltaTime;
                if (transfer.WaitTimer > 0.0f)
                {
                    continue;
                }

                transfer.WaitTimer = 0.05f;// transfer.Connection.AverageRoundtripTime;

                // send another part of the file
                long remaining     = transfer.Data.Length - transfer.SentOffset;
                int  sendByteCount = (remaining > chunkLen ? chunkLen : (int)remaining);

                IWriteMessage message;

                try
                {
                    //first message; send length, file name etc
                    //wait for acknowledgement before sending data
                    if (!transfer.Acknowledged)
                    {
                        message = new WriteOnlyMessage();
                        message.Write((byte)ServerPacketHeader.FILE_TRANSFER);

                        //if the recipient is the owner of the server (= a client running the server from the main exe)
                        //we don't need to send anything, the client can just read the file directly
                        if (transfer.Connection == GameMain.Server.OwnerConnection)
                        {
                            message.Write((byte)FileTransferMessageType.TransferOnSameMachine);
                            message.Write((byte)transfer.ID);
                            message.Write((byte)transfer.FileType);
                            message.Write(transfer.FilePath);
                            peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable);
                            transfer.Status = FileTransferStatus.Finished;
                        }
                        else
                        {
                            message.Write((byte)FileTransferMessageType.Initiate);
                            message.Write((byte)transfer.ID);
                            message.Write((byte)transfer.FileType);
                            //message.Write((ushort)chunkLen);
                            message.Write(transfer.Data.Length);
                            message.Write(transfer.FileName);
                            peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable);

                            transfer.Status = FileTransferStatus.Sending;

                            if (GameSettings.VerboseLogging)
                            {
                                DebugConsole.Log("Sending file transfer initiation message: ");
                                DebugConsole.Log("  File: " + transfer.FileName);
                                DebugConsole.Log("  Size: " + transfer.Data.Length);
                                DebugConsole.Log("  ID: " + transfer.ID);
                            }
                        }
                        return;
                    }

                    message = new WriteOnlyMessage();
                    message.Write((byte)ServerPacketHeader.FILE_TRANSFER);
                    message.Write((byte)FileTransferMessageType.Data);

                    message.Write((byte)transfer.ID);
                    message.Write(transfer.SentOffset);

                    byte[] sendBytes = new byte[sendByteCount];
                    Array.Copy(transfer.Data, transfer.SentOffset, sendBytes, 0, sendByteCount);

                    message.Write((ushort)sendByteCount);
                    message.Write(sendBytes, 0, sendByteCount);

                    transfer.SentOffset += sendByteCount;
                    if (transfer.SentOffset > transfer.KnownReceivedOffset + chunkLen * 5 ||
                        transfer.SentOffset >= transfer.Data.Length)
                    {
                        transfer.SentOffset = transfer.KnownReceivedOffset;
                    }

                    peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable);
                }

                catch (Exception e)
                {
                    DebugConsole.ThrowError("FileSender threw an exception when trying to send data", e);
                    GameAnalyticsManager.AddErrorEventOnce(
                        "FileSender.Update:Exception",
                        GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
                        "FileSender threw an exception when trying to send data:\n" + e.Message + "\n" + e.StackTrace);
                    transfer.Status = FileTransferStatus.Error;
                    break;
                }

                if (GameSettings.VerboseLogging)
                {
                    DebugConsole.Log("Sending " + sendByteCount + " bytes of the file " + transfer.FileName + " (" + transfer.SentOffset + "/" + transfer.Data.Length + " sent)");
                }
            }
        }
        private void Send(FileTransferOut transfer)
        {
            // send another part of the file
            long remaining     = transfer.Data.Length - transfer.SentOffset;
            int  sendByteCount = (remaining > chunkLen ? chunkLen : (int)remaining);

            IWriteMessage message;

            try
            {
                //first message; send length, file name etc
                //wait for acknowledgement before sending data
                if (!transfer.Acknowledged)
                {
                    message = new WriteOnlyMessage();
                    message.Write((byte)ServerPacketHeader.FILE_TRANSFER);

                    //if the recipient is the owner of the server (= a client running the server from the main exe)
                    //we don't need to send anything, the client can just read the file directly
                    if (transfer.Connection == GameMain.Server.OwnerConnection)
                    {
                        message.Write((byte)FileTransferMessageType.TransferOnSameMachine);
                        message.Write((byte)transfer.ID);
                        message.Write((byte)transfer.FileType);
                        message.Write(transfer.FilePath);
                        peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable);
                        transfer.Status = FileTransferStatus.Finished;
                    }
                    else
                    {
                        message.Write((byte)FileTransferMessageType.Initiate);
                        message.Write((byte)transfer.ID);
                        message.Write((byte)transfer.FileType);
                        //message.Write((ushort)chunkLen);
                        message.Write(transfer.Data.Length);
                        message.Write(transfer.FileName);
                        peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable);

                        transfer.Status = FileTransferStatus.Sending;

                        if (GameSettings.VerboseLogging)
                        {
                            DebugConsole.Log("Sending file transfer initiation message: ");
                            DebugConsole.Log("  File: " + transfer.FileName);
                            DebugConsole.Log("  Size: " + transfer.Data.Length);
                            DebugConsole.Log("  ID: " + transfer.ID);
                        }
                    }
                    transfer.WaitTimer = 0.1f;
                    return;
                }

                message = new WriteOnlyMessage();
                message.Write((byte)ServerPacketHeader.FILE_TRANSFER);
                message.Write((byte)FileTransferMessageType.Data);

                message.Write((byte)transfer.ID);
                message.Write(transfer.SentOffset);

                byte[] sendBytes = new byte[sendByteCount];
                Array.Copy(transfer.Data, transfer.SentOffset, sendBytes, 0, sendByteCount);

                message.Write((ushort)sendByteCount);
                message.Write(sendBytes, 0, sendByteCount);

                transfer.SentOffset += sendByteCount;
                if (transfer.SentOffset > transfer.KnownReceivedOffset + chunkLen * 10 ||
                    transfer.SentOffset >= transfer.Data.Length)
                {
                    transfer.SentOffset = transfer.KnownReceivedOffset;
                    transfer.WaitTimer  = 0.5f;
                }

                peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable);
            }

            catch (Exception e)
            {
                DebugConsole.ThrowError("FileSender threw an exception when trying to send data", e);
                GameAnalyticsManager.AddErrorEventOnce(
                    "FileSender.Update:Exception",
                    GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
                    "FileSender threw an exception when trying to send data:\n" + e.Message + "\n" + e.StackTrace.CleanupStackTrace());
                transfer.Status = FileTransferStatus.Error;
                return;
            }

            if (GameSettings.VerboseLogging)
            {
                DebugConsole.Log($"Sending {sendByteCount} bytes of the file {transfer.FileName} ({transfer.SentOffset / 1000}/{transfer.Data.Length / 1000} kB sent)");
            }
        }