Looks like a lot more than just netcode is getting rewritten. Removing coroutines because there are better ways of handling asynchronous tasks, removing filestream because that's to be reimplemented later
188 lines
5.3 KiB
C#
188 lines
5.3 KiB
C#
using Lidgren.Network;
|
|
using System;
|
|
using System.IO;
|
|
|
|
namespace Barotrauma.Networking
|
|
{
|
|
enum FileTransferStatus
|
|
{
|
|
NotStarted, Sending, Receiving, Finished, Error, Canceled
|
|
}
|
|
|
|
enum FileTransferMessageType
|
|
{
|
|
Unknown, Initiate, Submarine, Cancel
|
|
}
|
|
|
|
class FileStreamSender : IDisposable
|
|
{
|
|
public static TimeSpan MaxTransferDuration = new TimeSpan(0, 2, 0);
|
|
|
|
private FileStream inputStream;
|
|
private int sentOffset;
|
|
private int chunkLen;
|
|
private byte[] tempBuffer;
|
|
private NetConnection connection;
|
|
|
|
float waitTimer;
|
|
|
|
DateTime startingTime;
|
|
|
|
private FileTransferMessageType fileType;
|
|
|
|
public FileTransferStatus Status
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public string FileName
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public string FilePath
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public float Progress
|
|
{
|
|
get { return inputStream == null ? 0.0f : (float)sentOffset / (float)inputStream.Length; }
|
|
}
|
|
|
|
public int Sent
|
|
{
|
|
get { return sentOffset; }
|
|
}
|
|
|
|
public long FileSize
|
|
{
|
|
get { return inputStream == null ? 0 : inputStream.Length; }
|
|
}
|
|
|
|
public static FileStreamSender Create(NetConnection conn, string filePath, FileTransferMessageType fileType)
|
|
{
|
|
if (!File.Exists(filePath))
|
|
{
|
|
DebugConsole.ThrowError("Sending a file failed. File ''"+filePath+"'' not found.");
|
|
return null;
|
|
}
|
|
|
|
FileStreamSender sender = null;
|
|
|
|
try
|
|
{
|
|
sender = new FileStreamSender(conn, filePath, fileType);
|
|
}
|
|
|
|
catch (Exception e)
|
|
{
|
|
DebugConsole.ThrowError("Couldn't open file ''"+filePath+"''",e);
|
|
}
|
|
|
|
return sender;
|
|
}
|
|
|
|
private FileStreamSender(NetConnection conn, string filePath, FileTransferMessageType fileType)
|
|
{
|
|
connection = conn;
|
|
inputStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
chunkLen = connection.Peer.Configuration.MaximumTransmissionUnit - 100;
|
|
tempBuffer = new byte[chunkLen];
|
|
sentOffset = 0;
|
|
|
|
FilePath = filePath;
|
|
FileName = Path.GetFileName(filePath);
|
|
|
|
this.fileType = fileType;
|
|
|
|
Status = FileTransferStatus.NotStarted;
|
|
|
|
startingTime = DateTime.Now;
|
|
}
|
|
|
|
public void Update(float deltaTime)
|
|
{
|
|
if (inputStream == null ||
|
|
Status == FileTransferStatus.Canceled ||
|
|
Status == FileTransferStatus.Error ||
|
|
Status == FileTransferStatus.Finished) return;
|
|
|
|
if (DateTime.Now > startingTime + MaxTransferDuration)
|
|
{
|
|
CancelTransfer();
|
|
return;
|
|
}
|
|
|
|
waitTimer -= deltaTime;
|
|
if (waitTimer > 0.0f) return;
|
|
|
|
if (!connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, 1)) return;
|
|
|
|
// send another part of the file!
|
|
long remaining = inputStream.Length - sentOffset;
|
|
int sendBytes = (remaining > chunkLen ? chunkLen : (int)remaining);
|
|
|
|
// just assume we can read the whole thing in one Read()
|
|
inputStream.Read(tempBuffer, 0, sendBytes);
|
|
|
|
NetOutgoingMessage message;
|
|
if (sentOffset == 0)
|
|
{
|
|
// first message; send length, chunk length and file name
|
|
message = connection.Peer.CreateMessage(sendBytes + 8 + 1);
|
|
message.Write((byte)PacketTypes.FileStream);
|
|
message.Write((byte)FileTransferMessageType.Initiate);
|
|
message.Write((byte)fileType);
|
|
message.Write((ulong)inputStream.Length);
|
|
message.Write(Path.GetFileName(inputStream.Name));
|
|
connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, 1);
|
|
|
|
Status = FileTransferStatus.Sending;
|
|
}
|
|
|
|
message = connection.Peer.CreateMessage(sendBytes + 8 + 1);
|
|
message.Write((byte)PacketTypes.FileStream);
|
|
message.Write((byte)fileType);
|
|
message.Write(tempBuffer, 0, sendBytes);
|
|
|
|
connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, 1);
|
|
sentOffset += sendBytes;
|
|
|
|
waitTimer = connection.AverageRoundtripTime;
|
|
|
|
//Program.Output("Sent " + m_sentOffset + "/" + m_inputStream.Length + " bytes to " + m_connection);
|
|
|
|
if (remaining - sendBytes <= 0)
|
|
{
|
|
//Dispose();
|
|
|
|
Status = FileTransferStatus.Finished;
|
|
}
|
|
}
|
|
|
|
public void CancelTransfer()
|
|
{
|
|
Status = FileTransferStatus.Canceled;
|
|
}
|
|
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
inputStream.Close();
|
|
inputStream.Dispose();
|
|
inputStream = null;
|
|
}
|
|
}
|
|
}
|