Example #1
0
        public void CancelTransfer(FileTransferOut transfer)
        {
            transfer.Status = FileTransferStatus.Canceled;
            activeTransfers.Remove(transfer);

            OnEnded(transfer);

            GameMain.Server.SendCancelTransferMsg(transfer);
        }
Example #2
0
        public FileTransferOut StartTransfer(NetworkConnection recipient, FileTransferType fileType, string filePath)
        {
            if (activeTransfers.Count >= MaxTransferCount)
            {
                return(null);
            }

            if (activeTransfers.Count(t => t.Connection == recipient) > MaxTransferCountPerRecipient)
            {
                return(null);
            }

            if (!File.Exists(filePath))
            {
                DebugConsole.ThrowError("Failed to initiate file transfer (file \"" + filePath + "\" not found.");
                return(null);
            }

            FileTransferOut transfer = null;

            try
            {
                transfer = new FileTransferOut(recipient, fileType, filePath)
                {
                    ID = 1
                };
                while (activeTransfers.Any(t => t.Connection == recipient && t.ID == transfer.ID))
                {
                    transfer.ID++;
                }
                activeTransfers.Add(transfer);
            }
            catch (Exception e)
            {
                DebugConsole.ThrowError("Failed to initiate file transfer", e);
                return(null);
            }

            OnStarted(transfer);

            return(transfer);
        }
        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)");
            }
        }