Client-side file transfer UI, FileSender has a limit on how many transfers can be active simultaneously (todo: queue transfers?), some extra debug logging & small fixes

This commit is contained in:
Regalis
2017-03-08 22:56:11 +02:00
parent 64e866d771
commit ca402396a0
3 changed files with 95 additions and 9 deletions

View File

@@ -73,13 +73,21 @@ namespace Barotrauma.Networking
private set;
}
public NetConnection Connection
{
get;
private set;
}
public int SequenceChannel;
public FileTransferIn(string filePath, FileTransferType fileType)
public FileTransferIn(NetConnection connection, string filePath, FileTransferType fileType)
{
FilePath = filePath;
FileName = Path.GetFileName(FilePath);
FileType = fileType;
Connection = connection;
WriteStream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None);
TimeStarted = Environment.TickCount;
@@ -95,6 +103,11 @@ namespace Barotrauma.Networking
int passed = Environment.TickCount - TimeStarted;
float psec = passed / 1000.0f;
if (GameSettings.VerboseLogging)
{
DebugConsole.Log("Received "+all.Length+" bytes of the file "+FileName+" ("+Received+"/"+FileSize+" received)");
}
BytesPerSecond = Received / psec;
@@ -176,7 +189,15 @@ namespace Barotrauma.Networking
return;
}
var newTransfer = new FileTransferIn(Path.Combine(downloadFolder, fileName), (FileTransferType)fileType);
if (GameSettings.VerboseLogging)
{
DebugConsole.Log("Received file transfer initiation message: ");
DebugConsole.Log(" File: "+fileName);
DebugConsole.Log(" Size: " + fileSize);
DebugConsole.Log(" Sequence channel: " + inc.SequenceChannel);
}
var newTransfer = new FileTransferIn(inc.SenderConnection, Path.Combine(downloadFolder, fileName), (FileTransferType)fileType);
newTransfer.SequenceChannel = inc.SequenceChannel;
newTransfer.Status = FileTransferStatus.Receiving;
newTransfer.FileSize = fileSize;
@@ -185,7 +206,7 @@ namespace Barotrauma.Networking
break;
case (byte)FileTransferMessageType.Data:
var activeTransfer = activeTransfers.Find(t => t.SequenceChannel == inc.SequenceChannel);
var activeTransfer = activeTransfers.Find(t => t.Connection == inc.SenderConnection && t.SequenceChannel == inc.SequenceChannel);
if (activeTransfer == null)
{
DebugConsole.ThrowError("File transfer error: received data without a transfer initiation message");
@@ -231,6 +252,12 @@ namespace Barotrauma.Networking
}
}
break;
case (byte)FileTransferMessageType.Cancel:
byte sequenceChannel = inc.ReadByte();
var matchingTransfer = activeTransfers.Find(t => t.Connection == inc.SenderConnection && t.SequenceChannel == sequenceChannel);
if (matchingTransfer != null) StopTransfer(matchingTransfer);
break;
}
}

View File

@@ -98,6 +98,9 @@ namespace Barotrauma.Networking
}
}
const int MaxTransferCount = 16;
const int MaxTransferCountPerRecipient = 5;
public static TimeSpan MaxTransferDuration = new TimeSpan(0, 2, 0);
private List<FileTransferOut> activeTransfers;
@@ -116,7 +119,16 @@ namespace Barotrauma.Networking
public FileTransferOut StartTransfer(NetConnection recipient, FileTransferType fileType, string filePath)
{
//TODO: set a limit on the amount of active transfers
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.");
@@ -149,7 +161,7 @@ namespace Barotrauma.Networking
foreach (FileTransferOut transfer in activeTransfers)
{
transfer.WaitTimer -= deltaTime;
if (transfer.WaitTimer > 0.0f) return;
if (transfer.WaitTimer > 0.0f) continue;
if (!transfer.Connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, 1)) continue;
@@ -164,7 +176,7 @@ namespace Barotrauma.Networking
//first message; send length, chunk length, file name etc
if (transfer.SentOffset == 0)
{
message = peer.CreateMessage(sendByteCount + 8 + 1);
message = peer.CreateMessage();
message.Write((byte)ServerPacketHeader.FILE_TRANSFER);
message.Write((byte)FileTransferMessageType.Initiate);
message.Write((byte)transfer.FileType);
@@ -174,9 +186,17 @@ namespace Barotrauma.Networking
transfer.Connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel);
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(" Sequence channel: " + transfer.SequenceChannel);
}
}
message = peer.CreateMessage(sendByteCount + 8 + 1);
message = peer.CreateMessage(1 + 1 + sendByteCount);
message.Write((byte)ServerPacketHeader.FILE_TRANSFER);
message.Write((byte)FileTransferMessageType.Data);
@@ -187,7 +207,12 @@ namespace Barotrauma.Networking
transfer.Connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel);
transfer.SentOffset += sendByteCount;
if (GameSettings.VerboseLogging)
{
DebugConsole.Log("Sending " + sendByteCount + " bytes of the file " + transfer.FileName + " (" + transfer.SentOffset + "/" + transfer.Data.Length + " sent)");
}
if (remaining - sendByteCount <= 0)
{
transfer.Status = FileTransferStatus.Finished;

View File

@@ -1036,7 +1036,41 @@ namespace Barotrauma.Networking
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
{
base.Draw(spriteBatch);
if (fileReceiver != null && fileReceiver.ActiveTransfers.Count > 0)
{
Vector2 pos = new Vector2(GameMain.NetLobbyScreen.InfoFrame.Rect.X, GameMain.GraphicsHeight - 35);
GUI.DrawRectangle(spriteBatch, new Rectangle(
(int)pos.X,
(int)pos.Y,
fileReceiver.ActiveTransfers.Count * 210 + 10,
32),
Color.Black * 0.8f, true);
for (int i = 0; i < fileReceiver.ActiveTransfers.Count; i++)
{
var transfer = fileReceiver.ActiveTransfers[i];
GameMain.NetLobbyScreen.SubList.children.Find(c => c is GUITextBlock && ((GUITextBlock)c).Text == transfer.FileName);
GUI.DrawString(spriteBatch,
pos,
ToolBox.LimitString("Downloading " + transfer.FileName, GUI.SmallFont, 200),
Color.White, null, 0, GUI.SmallFont);
GUI.DrawProgressBar(spriteBatch, new Vector2(pos.X, -pos.Y - 15), new Vector2(135, 15), transfer.Progress, Color.Green);
GUI.DrawString(spriteBatch, pos + new Vector2(5, 15),
MathUtils.GetBytesReadable((long)transfer.Received) + " / " + MathUtils.GetBytesReadable((long)transfer.FileSize),
Color.White, null, 0, GUI.SmallFont);
if (GUI.DrawButton(spriteBatch, new Rectangle((int)pos.X + 140, (int)pos.Y + 15, 60, 15), "Cancel", new Color(0.47f, 0.13f, 0.15f, 0.08f)))
{
fileReceiver.StopTransfer(transfer);
}
pos.X += 210;
}
}
if (!GameMain.DebugDraw) return;
int width = 200, height = 300;