DownloadManager works!

This commit is contained in:
EntenKoeniq
2022-04-03 02:27:30 +02:00
parent 7c194f38a6
commit 989dcaeb0b
8 changed files with 296 additions and 50 deletions

View File

@ -2,12 +2,13 @@
using System.Linq;
using System.Collections.Generic;
using Lidgren.Network;
using System;
namespace CoopServer
{
internal static class DownloadManager
{
const int MAX_BUFFER = 1048576; // 1MB
private static readonly List<DownloadClient> _clients = new();
private static readonly List<DownloadFile> _files = new();
public static bool AnyFileExists = false;
@ -19,19 +20,28 @@ namespace CoopServer
return;
}
_clients.Add(new DownloadClient() { NetHandle = nethandle, FilesCount = _files.Count });
_clients.Add(new DownloadClient(nethandle, _files));
}
public static bool CheckForDirectoryAndFiles()
{
string[] filePaths = Directory.GetFiles("clientside");
string[] filePaths;
if (!Directory.Exists("clientside") || filePaths.Length == 0)
if (!Directory.Exists("clientside"))
{
AnyFileExists = false;
return false;
}
filePaths = Directory.GetFiles("clientside");
if (filePaths.Length == 0)
{
AnyFileExists = false;
return false;
}
byte fileCount = 0;
foreach (string file in filePaths)
{
FileInfo fileInfo = new(file);
@ -43,18 +53,15 @@ namespace CoopServer
continue;
}
Logging.Debug($"===== {fileInfo.Name} =====");
int MAX_BUFFER = fileInfo.Length < 5120 ? (int)fileInfo.Length : 5120; // 5KB
byte[] buffer = new byte[MAX_BUFFER];
int bytesRead = 0;
bool fileCreated = false;
DownloadFile newFile = null;
byte fileCount = 0;
using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read))
using (BufferedStream bs = new(fs))
{
while ((bytesRead = bs.Read(buffer, 0, MAX_BUFFER)) != 0) // Reading 1MB chunks at time
while (bs.Read(buffer, 0, MAX_BUFFER) != 0) // Reading 5KB chunks at time
{
if (!fileCreated)
{
@ -63,12 +70,11 @@ namespace CoopServer
}
newFile.AddData(buffer);
Logging.Debug($"{bytesRead}");
}
}
_files.Add(newFile);
fileCount++;
}
Logging.Info($"{_files.Count} files found!");
@ -81,12 +87,12 @@ namespace CoopServer
{
_clients.ForEach(client =>
{
if (!client.SendFiles(_files))
if (!client.SendFiles())
{
Client x = Server.Clients.FirstOrDefault(x => x.NetHandle == client.NetHandle);
if (x != null)
{
x.FilesSent = true;
x.FilesReceived = true;
}
}
});
@ -100,60 +106,117 @@ namespace CoopServer
_clients.Remove(client);
}
}
/// <summary>
/// We try to remove the client when all files have been sent
/// </summary>
/// <param name="nethandle"></param>
/// <param name="id"></param>
public static void TryToRemoveClient(long nethandle, int id)
{
DownloadClient client = _clients.FirstOrDefault(x => x.NetHandle == nethandle);
if (client == null)
{
return;
}
client.FilePosition++;
if (client.DownloadComplete())
{
_clients.Remove(client);
}
}
}
internal class DownloadClient
{
public long NetHandle { get; set; }
public int FilesCount { get; set; }
public int FilesSent = 0;
public long NetHandle = 0;
private List<DownloadFile> Files = null;
public int FilePosition = 0;
public DownloadClient(long nethandle, List<DownloadFile> files)
{
NetHandle = nethandle;
Files = files;
NetConnection conn = Server.MainNetServer.Connections.FirstOrDefault(x => x.RemoteUniqueIdentifier == NetHandle);
if (conn != null)
{
Files.ForEach(file =>
{
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
new Packets.FileRequest()
{
ID = file.FileID,
FileType = (byte)Packets.DataFileType.Script,
FileName = file.FileName,
FileLength = file.FileLength
}.PacketToNetOutGoingMessage(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, conn, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.File);
});
}
}
/// <summary>
///
/// </summary>
/// <returns>true if files should be sent otherwise false</returns>
public bool SendFiles(List<DownloadFile> files)
public bool SendFiles()
{
if (FilesSent >= FilesCount)
if (DownloadComplete())
{
return false;
}
DownloadFile file = files.FirstOrDefault(x => !x.DownloadFinished());
if (file == null)
{
return false;
}
DownloadFile file = Files[FilePosition];
file.Send(NetHandle);
// Check it again, maybe this file is finish now
if (file.DownloadFinished())
{
FilesSent++;
FilePosition++;
if (FilesSent >= FilesCount)
{
return false;
}
return DownloadComplete();
}
return true;
}
public bool DownloadComplete()
{
return FilePosition >= Files.Count;
}
}
internal class DownloadFile
{
public int FileID { get; set; }
public byte FileID { get; set; }
public string FileName { get; set; }
public long FileLength { get; set; }
private readonly List<byte[]> _data = new();
private readonly long _sent = 0;
private int _dataPosition = 0;
public void Send(long nethandle)
{
// TODO
NetConnection conn = Server.MainNetServer.Connections.FirstOrDefault(x => x.RemoteUniqueIdentifier == nethandle);
if (conn == null)
{
return;
}
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
new Packets.FileTransferTick() { ID = FileID, FileChunk = _data.ElementAt(_dataPosition) }.PacketToNetOutGoingMessage(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, conn, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.File);
Logging.Debug($"Send _data[{_dataPosition}] ~ {_data.ElementAt(_dataPosition).Length}");
_dataPosition++;
}
public void AddData(byte[] data)
@ -161,9 +224,14 @@ namespace CoopServer
_data.Add(data);
}
public void Cancel()
{
_dataPosition = _data.Count - 1;
}
public bool DownloadFinished()
{
return _sent >= FileLength;
return _dataPosition >= _data.Count;
}
}
}