File transfers (somewhat) working. Todo: testing, show active transfers in the UI
This commit is contained in:
@@ -14,9 +14,6 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
public class FileTransferIn : IDisposable
|
public class FileTransferIn : IDisposable
|
||||||
{
|
{
|
||||||
public delegate void OnFinishedDelegate(FileTransferIn fileStreamReceiver);
|
|
||||||
public OnFinishedDelegate OnFinished;
|
|
||||||
|
|
||||||
public string FileName
|
public string FileName
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -32,7 +29,7 @@ namespace Barotrauma.Networking
|
|||||||
public ulong FileSize
|
public ulong FileSize
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
private set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong Received
|
public ulong Received
|
||||||
@@ -78,14 +75,12 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public int SequenceChannel;
|
public int SequenceChannel;
|
||||||
|
|
||||||
public FileTransferIn(string filePath, FileTransferType fileType, OnFinishedDelegate onFinished)
|
public FileTransferIn(string filePath, FileTransferType fileType)
|
||||||
{
|
{
|
||||||
FilePath = filePath;
|
FilePath = filePath;
|
||||||
FileName = Path.GetFileName(FilePath);
|
FileName = Path.GetFileName(FilePath);
|
||||||
FileType = fileType;
|
FileType = fileType;
|
||||||
|
|
||||||
this.OnFinished = onFinished;
|
|
||||||
|
|
||||||
WriteStream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None);
|
WriteStream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||||
TimeStarted = Environment.TickCount;
|
TimeStarted = Environment.TickCount;
|
||||||
|
|
||||||
@@ -132,10 +127,18 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
const int MaxFileSize = 1000000;
|
const int MaxFileSize = 1000000;
|
||||||
|
|
||||||
|
public delegate void OnFinishedDelegate(FileTransferIn fileStreamReceiver);
|
||||||
|
public OnFinishedDelegate OnFinished;
|
||||||
|
|
||||||
private List<FileTransferIn> activeTransfers;
|
private List<FileTransferIn> activeTransfers;
|
||||||
|
|
||||||
private string downloadFolder;
|
private string downloadFolder;
|
||||||
|
|
||||||
|
public List<FileTransferIn> ActiveTransfers
|
||||||
|
{
|
||||||
|
get { return activeTransfers; }
|
||||||
|
}
|
||||||
|
|
||||||
public FileReceiver(string downloadFolder)
|
public FileReceiver(string downloadFolder)
|
||||||
{
|
{
|
||||||
activeTransfers = new List<FileTransferIn>();
|
activeTransfers = new List<FileTransferIn>();
|
||||||
@@ -143,7 +146,7 @@ namespace Barotrauma.Networking
|
|||||||
this.downloadFolder = downloadFolder;
|
this.downloadFolder = downloadFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadMessage(NetIncomingMessage inc)
|
public void ReadMessage(NetIncomingMessage inc)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Assert(!activeTransfers.Any(t =>
|
System.Diagnostics.Debug.Assert(!activeTransfers.Any(t =>
|
||||||
t.Status == FileTransferStatus.Error ||
|
t.Status == FileTransferStatus.Error ||
|
||||||
@@ -173,9 +176,10 @@ namespace Barotrauma.Networking
|
|||||||
return;
|
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.SequenceChannel = inc.SequenceChannel;
|
||||||
newTransfer.Status = FileTransferStatus.Receiving;
|
newTransfer.Status = FileTransferStatus.Receiving;
|
||||||
|
newTransfer.FileSize = fileSize;
|
||||||
|
|
||||||
activeTransfers.Add(newTransfer);
|
activeTransfers.Add(newTransfer);
|
||||||
|
|
||||||
@@ -188,10 +192,11 @@ namespace Barotrauma.Networking
|
|||||||
return;
|
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");
|
DebugConsole.ThrowError("File transfer error: Received more data than expected");
|
||||||
activeTransfer.Status = FileTransferStatus.Error;
|
activeTransfer.Status = FileTransferStatus.Error;
|
||||||
|
StopTransfer(activeTransfer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,14 +214,18 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (activeTransfer.Status == FileTransferStatus.Finished)
|
if (activeTransfer.Status == FileTransferStatus.Finished)
|
||||||
{
|
{
|
||||||
|
activeTransfer.Dispose();
|
||||||
|
|
||||||
string errorMessage = "";
|
string errorMessage = "";
|
||||||
if (ValidateReceivedData(activeTransfer, out errorMessage))
|
if (ValidateReceivedData(activeTransfer, out errorMessage))
|
||||||
{
|
{
|
||||||
activeTransfer.OnFinished(activeTransfer);
|
OnFinished(activeTransfer);
|
||||||
StopTransfer(activeTransfer);
|
StopTransfer(activeTransfer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
new GUIMessageBox("File transfer aborted", errorMessage);
|
||||||
|
|
||||||
activeTransfer.Status = FileTransferStatus.Error;
|
activeTransfer.Status = FileTransferStatus.Error;
|
||||||
StopTransfer(activeTransfer, true);
|
StopTransfer(activeTransfer, true);
|
||||||
}
|
}
|
||||||
@@ -236,7 +245,7 @@ namespace Barotrauma.Networking
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Enum.IsDefined(typeof(FileTransferType), type))
|
if (!Enum.IsDefined(typeof(FileTransferType), (int)type))
|
||||||
{
|
{
|
||||||
errorMessage = "Unknown file type";
|
errorMessage = "Unknown file type";
|
||||||
return false;
|
return false;
|
||||||
@@ -318,6 +327,15 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void StopTransfer(FileTransferIn transfer, bool deleteFile = false)
|
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))
|
if (deleteFile && File.Exists(transfer.FilePath))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -329,15 +347,6 @@ namespace Barotrauma.Networking
|
|||||||
DebugConsole.ThrowError("Failed to delete file \""+transfer.FilePath+"\" ("+e.Message+")");
|
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
transfer.SequenceChannel++;
|
transfer.SequenceChannel++;
|
||||||
}
|
}
|
||||||
|
activeTransfers.Add(transfer);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -173,7 +174,6 @@ namespace Barotrauma.Networking
|
|||||||
transfer.Connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel);
|
transfer.Connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel);
|
||||||
|
|
||||||
transfer.Status = FileTransferStatus.Sending;
|
transfer.Status = FileTransferStatus.Sending;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message = peer.CreateMessage(sendByteCount + 8 + 1);
|
message = peer.CreateMessage(sendByteCount + 8 + 1);
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
private ClientEntityEventManager entityEventManager;
|
private ClientEntityEventManager entityEventManager;
|
||||||
|
|
||||||
|
private FileReceiver fileReceiver;
|
||||||
|
|
||||||
public byte ID
|
public byte ID
|
||||||
{
|
{
|
||||||
get { return myID; }
|
get { return myID; }
|
||||||
@@ -56,6 +58,11 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FileReceiver FileReceiver
|
||||||
|
{
|
||||||
|
get { return fileReceiver; }
|
||||||
|
}
|
||||||
|
|
||||||
public GameClient(string newName)
|
public GameClient(string newName)
|
||||||
{
|
{
|
||||||
endVoteTickBox = new GUITickBox(new Rectangle(GameMain.GraphicsWidth - 170, 20, 20, 20), "End round", Alignment.TopLeft, inGameHUD);
|
endVoteTickBox = new GUITickBox(new Rectangle(GameMain.GraphicsWidth - 170, 20, 20, 20), "End round", Alignment.TopLeft, inGameHUD);
|
||||||
@@ -84,6 +91,9 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
entityEventManager = new ClientEntityEventManager(this);
|
entityEventManager = new ClientEntityEventManager(this);
|
||||||
|
|
||||||
|
fileReceiver = new FileReceiver("Submarines/Downloaded");
|
||||||
|
fileReceiver.OnFinished += OnFileReceived;
|
||||||
|
|
||||||
characterInfo = new CharacterInfo(Character.HumanConfigFile, name);
|
characterInfo = new CharacterInfo(Character.HumanConfigFile, name);
|
||||||
characterInfo.Job = null;
|
characterInfo.Job = null;
|
||||||
|
|
||||||
@@ -542,6 +552,9 @@ namespace Barotrauma.Networking
|
|||||||
case ServerPacketHeader.PERMISSIONS:
|
case ServerPacketHeader.PERMISSIONS:
|
||||||
ReadPermissions(inc);
|
ReadPermissions(inc);
|
||||||
break;
|
break;
|
||||||
|
case ServerPacketHeader.FILE_TRANSFER:
|
||||||
|
fileReceiver.ReadMessage(inc);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NetIncomingMessageType.StatusChanged:
|
case NetIncomingMessageType.StatusChanged:
|
||||||
@@ -976,6 +989,40 @@ namespace Barotrauma.Networking
|
|||||||
chatMsgQueue.Add(chatMessage);
|
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)
|
public void CreateEntityEvent(IClientSerializable entity, object[] extraData)
|
||||||
{
|
{
|
||||||
entityEventManager.CreateEvent(entity, extraData);
|
entityEventManager.CreateEvent(entity, extraData);
|
||||||
|
|||||||
@@ -134,8 +134,6 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
entityEventManager = new ServerEntityEventManager(this);
|
entityEventManager = new ServerEntityEventManager(this);
|
||||||
|
|
||||||
fileSender = new FileSender(this);
|
|
||||||
|
|
||||||
whitelist = new WhiteList();
|
whitelist = new WhiteList();
|
||||||
banList = new BanList();
|
banList = new BanList();
|
||||||
|
|
||||||
@@ -155,6 +153,8 @@ namespace Barotrauma.Networking
|
|||||||
Log("Starting the server...", Color.Cyan);
|
Log("Starting the server...", Color.Cyan);
|
||||||
server = new NetServer(config);
|
server = new NetServer(config);
|
||||||
netPeer = server;
|
netPeer = server;
|
||||||
|
fileSender = new FileSender(this);
|
||||||
|
|
||||||
server.Start();
|
server.Start();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -558,7 +558,7 @@ namespace Barotrauma.Networking
|
|||||||
case ClientPacketHeader.FILE_REQUEST:
|
case ClientPacketHeader.FILE_REQUEST:
|
||||||
if (AllowFileTransfers)
|
if (AllowFileTransfers)
|
||||||
{
|
{
|
||||||
|
fileSender.ReadFileRequest(inc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1188,8 +1188,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool TrySelectSub(string subName, string md5Hash, GUIListBox subList)
|
public bool TrySelectSub(string subName, string md5Hash, GUIListBox subList)
|
||||||
{
|
{
|
||||||
|
if (GameMain.Client == null) return false;
|
||||||
|
|
||||||
//already downloading the selected sub file
|
//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;
|
var matchingListSub = subList.children.Find(c => c.UserData != null && (c.UserData as Submarine).Name == subName) as GUITextBlock;
|
||||||
if (matchingListSub != null)
|
if (matchingListSub != null)
|
||||||
@@ -1220,11 +1225,9 @@ namespace Barotrauma
|
|||||||
+ "Server's MD5 hash: " + md5Hash + ". ";
|
+ "Server's MD5 hash: " + md5Hash + ". ";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*string downloadMsg = string.IsNullOrEmpty(GameMain.Client.ActiveFileTransferName) ?
|
errorMsg += "Do you want to download the file from the server host?";
|
||||||
"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)
|
if (GUIMessageBox.MessageBoxes.Count > 0)
|
||||||
{
|
{
|
||||||
var currentMessageBox = GUIMessageBox.VisibleBox;
|
var currentMessageBox = GUIMessageBox.VisibleBox;
|
||||||
if (currentMessageBox != null && currentMessageBox.UserData as string == subName)
|
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].UserData = subName;
|
||||||
requestFileBox.Buttons[0].OnClicked += requestFileBox.Close;
|
requestFileBox.Buttons[0].OnClicked += requestFileBox.Close;
|
||||||
requestFileBox.Buttons[0].OnClicked += (GUIButton button, object userdata) =>
|
requestFileBox.Buttons[0].OnClicked += (GUIButton button, object userdata) =>
|
||||||
{
|
{
|
||||||
GameMain.Client.RequestFile(userdata.ToString(), FileTransferMessageType.Submarine);
|
GameMain.Client.RequestFile(userdata.ToString(), FileTransferType.Submarine);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
requestFileBox.Buttons[1].OnClicked += requestFileBox.Close;*/
|
requestFileBox.Buttons[1].OnClicked += requestFileBox.Close;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user