File transfers (somewhat) working. Todo: testing, show active transfers in the UI

This commit is contained in:
Regalis
2017-03-07 23:01:01 +02:00
parent 5450ff498a
commit 6bae2cf47b
5 changed files with 96 additions and 37 deletions

View File

@@ -13,10 +13,7 @@ namespace Barotrauma.Networking
class FileReceiver
{
public class FileTransferIn : IDisposable
{
public delegate void OnFinishedDelegate(FileTransferIn fileStreamReceiver);
public OnFinishedDelegate OnFinished;
{
public string FileName
{
get;
@@ -32,7 +29,7 @@ namespace Barotrauma.Networking
public ulong FileSize
{
get;
private set;
set;
}
public ulong Received
@@ -78,14 +75,12 @@ namespace Barotrauma.Networking
public int SequenceChannel;
public FileTransferIn(string filePath, FileTransferType fileType, OnFinishedDelegate onFinished)
public FileTransferIn(string filePath, FileTransferType fileType)
{
FilePath = filePath;
FileName = Path.GetFileName(FilePath);
FileType = fileType;
this.OnFinished = onFinished;
WriteStream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None);
TimeStarted = Environment.TickCount;
@@ -131,11 +126,19 @@ namespace Barotrauma.Networking
}
const int MaxFileSize = 1000000;
public delegate void OnFinishedDelegate(FileTransferIn fileStreamReceiver);
public OnFinishedDelegate OnFinished;
private List<FileTransferIn> activeTransfers;
private string downloadFolder;
public List<FileTransferIn> ActiveTransfers
{
get { return activeTransfers; }
}
public FileReceiver(string downloadFolder)
{
activeTransfers = new List<FileTransferIn>();
@@ -143,7 +146,7 @@ namespace Barotrauma.Networking
this.downloadFolder = downloadFolder;
}
private void ReadMessage(NetIncomingMessage inc)
public void ReadMessage(NetIncomingMessage inc)
{
System.Diagnostics.Debug.Assert(!activeTransfers.Any(t =>
t.Status == FileTransferStatus.Error ||
@@ -173,9 +176,10 @@ namespace Barotrauma.Networking
return;
}
var newTransfer = new FileTransferIn(Path.Combine(downloadFolder, fileName), (FileTransferType)fileType, null);
var newTransfer = new FileTransferIn(Path.Combine(downloadFolder, fileName), (FileTransferType)fileType);
newTransfer.SequenceChannel = inc.SequenceChannel;
newTransfer.Status = FileTransferStatus.Receiving;
newTransfer.FileSize = fileSize;
activeTransfers.Add(newTransfer);
@@ -188,10 +192,11 @@ namespace Barotrauma.Networking
return;
}
if (activeTransfer.Received + (ulong)inc.LengthBytes > activeTransfer.FileSize * 1.1f)
if (activeTransfer.Received + (ulong)(inc.LengthBytes-inc.PositionInBytes) > activeTransfer.FileSize)
{
DebugConsole.ThrowError("File transfer error: Received more data than expected");
activeTransfer.Status = FileTransferStatus.Error;
activeTransfer.Status = FileTransferStatus.Error;
StopTransfer(activeTransfer);
return;
}
@@ -209,14 +214,18 @@ namespace Barotrauma.Networking
if (activeTransfer.Status == FileTransferStatus.Finished)
{
activeTransfer.Dispose();
string errorMessage = "";
if (ValidateReceivedData(activeTransfer, out errorMessage))
{
activeTransfer.OnFinished(activeTransfer);
OnFinished(activeTransfer);
StopTransfer(activeTransfer);
}
else
{
new GUIMessageBox("File transfer aborted", errorMessage);
activeTransfer.Status = FileTransferStatus.Error;
StopTransfer(activeTransfer, true);
}
@@ -236,7 +245,7 @@ namespace Barotrauma.Networking
return false;
}
if (!Enum.IsDefined(typeof(FileTransferType), type))
if (!Enum.IsDefined(typeof(FileTransferType), (int)type))
{
errorMessage = "Unknown file type";
return false;
@@ -318,6 +327,15 @@ namespace Barotrauma.Networking
public void StopTransfer(FileTransferIn transfer, bool deleteFile = false)
{
if (transfer.Status != FileTransferStatus.Finished &&
transfer.Status != FileTransferStatus.Error)
{
transfer.Status = FileTransferStatus.Canceled;
}
if (activeTransfers.Contains(transfer)) activeTransfers.Remove(transfer);
transfer.Dispose();
if (deleteFile && File.Exists(transfer.FilePath))
{
try
@@ -329,15 +347,6 @@ namespace Barotrauma.Networking
DebugConsole.ThrowError("Failed to delete file \""+transfer.FilePath+"\" ("+e.Message+")");
}
}
if (transfer.Status != FileTransferStatus.Finished &&
transfer.Status != FileTransferStatus.Error)
{
transfer.Status = FileTransferStatus.Canceled;
}
if (activeTransfers.Contains(transfer)) activeTransfers.Remove(transfer);
transfer.Dispose();
}
}
}

View File

@@ -132,6 +132,7 @@ namespace Barotrauma.Networking
{
transfer.SequenceChannel++;
}
activeTransfers.Add(transfer);
}
catch (Exception e)
{
@@ -173,7 +174,6 @@ namespace Barotrauma.Networking
transfer.Connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel);
transfer.Status = FileTransferStatus.Sending;
continue;
}
message = peer.CreateMessage(sendByteCount + 8 + 1);

View File

@@ -43,6 +43,8 @@ namespace Barotrauma.Networking
private ClientEntityEventManager entityEventManager;
private FileReceiver fileReceiver;
public byte ID
{
get { return myID; }
@@ -55,6 +57,11 @@ namespace Barotrauma.Networking
return otherClients;
}
}
public FileReceiver FileReceiver
{
get { return fileReceiver; }
}
public GameClient(string newName)
{
@@ -83,6 +90,9 @@ namespace Barotrauma.Networking
name = newName;
entityEventManager = new ClientEntityEventManager(this);
fileReceiver = new FileReceiver("Submarines/Downloaded");
fileReceiver.OnFinished += OnFileReceived;
characterInfo = new CharacterInfo(Character.HumanConfigFile, name);
characterInfo.Job = null;
@@ -542,6 +552,9 @@ namespace Barotrauma.Networking
case ServerPacketHeader.PERMISSIONS:
ReadPermissions(inc);
break;
case ServerPacketHeader.FILE_TRANSFER:
fileReceiver.ReadMessage(inc);
break;
}
break;
case NetIncomingMessageType.StatusChanged:
@@ -976,6 +989,40 @@ namespace Barotrauma.Networking
chatMsgQueue.Add(chatMessage);
}
public void RequestFile(string file, FileTransferType fileType)
{
NetOutgoingMessage msg = client.CreateMessage();
msg.Write((byte)ClientPacketHeader.FILE_REQUEST);
msg.Write((byte)FileTransferMessageType.Initiate);
msg.Write((byte)fileType);
msg.Write(file);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
}
private void OnFileReceived(FileReceiver.FileTransferIn transfer)
{
new GUIMessageBox("Download finished", "File \"" + transfer.FileName + "\" was downloaded succesfully.");
switch (transfer.FileType)
{
case FileTransferType.Submarine:
Submarine.SavedSubmarines.RemoveAll(s => s.Name + ".sub" == transfer.FileName);
for (int i = 0; i < 2; i++)
{
var textBlock = ((i == 0) ?
GameMain.NetLobbyScreen.ShuttleList.ListBox.children.Find(c => (c.UserData as Submarine).Name + ".sub" == transfer.FileName) :
GameMain.NetLobbyScreen.SubList.children.Find(c => (c.UserData as Submarine).Name + ".sub" == transfer.FileName)) as GUITextBlock;
if (textBlock == null) continue;
textBlock.TextColor = Color.White;
var newSub = new Submarine(transfer.FilePath);
Submarine.SavedSubmarines.Add(newSub);
textBlock.UserData = newSub;
textBlock.ToolTip = newSub.Description;
}
break;
}
}
public void CreateEntityEvent(IClientSerializable entity, object[] extraData)
{
entityEventManager.CreateEvent(entity, extraData);

View File

@@ -134,8 +134,6 @@ namespace Barotrauma.Networking
entityEventManager = new ServerEntityEventManager(this);
fileSender = new FileSender(this);
whitelist = new WhiteList();
banList = new BanList();
@@ -155,6 +153,8 @@ namespace Barotrauma.Networking
Log("Starting the server...", Color.Cyan);
server = new NetServer(config);
netPeer = server;
fileSender = new FileSender(this);
server.Start();
}
catch (Exception e)
@@ -558,7 +558,7 @@ namespace Barotrauma.Networking
case ClientPacketHeader.FILE_REQUEST:
if (AllowFileTransfers)
{
fileSender.ReadFileRequest(inc);
}
break;
}

View File

@@ -1188,8 +1188,13 @@ namespace Barotrauma
public bool TrySelectSub(string subName, string md5Hash, GUIListBox subList)
{
if (GameMain.Client == null) return false;
//already downloading the selected sub file
//if (GameMain.Client.ActiveFileTransferName == subName+".sub") return false;
if (GameMain.Client.FileReceiver.ActiveTransfers.Any(t => t.FileName == subName + ".sub"))
{
return false;
}
var matchingListSub = subList.children.Find(c => c.UserData != null && (c.UserData as Submarine).Name == subName) as GUITextBlock;
if (matchingListSub != null)
@@ -1219,12 +1224,10 @@ namespace Barotrauma
+ "Your MD5 hash: " + sub.MD5Hash.Hash + " \n"
+ "Server's MD5 hash: " + md5Hash + ". ";
}
/*string downloadMsg = string.IsNullOrEmpty(GameMain.Client.ActiveFileTransferName) ?
"Do you want to download the file from the server host?" :
"Do you want to download the file and cancel downloading ''" + GameMain.Client.ActiveFileTransferName + "''?";*/
if (GUIMessageBox.MessageBoxes.Count>0)
errorMsg += "Do you want to download the file from the server host?";
if (GUIMessageBox.MessageBoxes.Count > 0)
{
var currentMessageBox = GUIMessageBox.VisibleBox;
if (currentMessageBox != null && currentMessageBox.UserData as string == subName)
@@ -1233,15 +1236,15 @@ namespace Barotrauma
}
}
/*var requestFileBox = new GUIMessageBox("Submarine not found!", errorMsg+downloadMsg, new string[] { "Yes", "No" }, 400, 300);
var requestFileBox = new GUIMessageBox("Submarine not found!", errorMsg, new string[] { "Yes", "No" }, 400, 300);
requestFileBox.Buttons[0].UserData = subName;
requestFileBox.Buttons[0].OnClicked += requestFileBox.Close;
requestFileBox.Buttons[0].OnClicked += (GUIButton button, object userdata) =>
{
GameMain.Client.RequestFile(userdata.ToString(), FileTransferMessageType.Submarine);
GameMain.Client.RequestFile(userdata.ToString(), FileTransferType.Submarine);
return true;
};
requestFileBox.Buttons[1].OnClicked += requestFileBox.Close;*/
requestFileBox.Buttons[1].OnClicked += requestFileBox.Close;
return false;
}