2022-04-02 19:12:15 +02:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
2022-04-03 02:27:30 +02:00
|
|
|
|
using Lidgren.Network;
|
|
|
|
|
using System;
|
|
|
|
|
|
2022-04-02 19:12:15 +02:00
|
|
|
|
namespace CoopServer
|
|
|
|
|
{
|
2022-04-02 23:02:49 +02:00
|
|
|
|
internal static class DownloadManager
|
2022-04-02 19:12:15 +02:00
|
|
|
|
{
|
2022-04-02 23:02:49 +02:00
|
|
|
|
private static readonly List<DownloadClient> _clients = new();
|
|
|
|
|
private static readonly List<DownloadFile> _files = new();
|
|
|
|
|
public static bool AnyFileExists = false;
|
2022-04-02 19:12:15 +02:00
|
|
|
|
|
2022-04-02 23:02:49 +02:00
|
|
|
|
public static void InsertClient(long nethandle)
|
2022-04-02 19:12:15 +02:00
|
|
|
|
{
|
2022-04-02 23:02:49 +02:00
|
|
|
|
if (!AnyFileExists)
|
2022-04-02 19:12:15 +02:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-03 02:27:30 +02:00
|
|
|
|
_clients.Add(new DownloadClient(nethandle, _files));
|
2022-04-02 23:02:49 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool CheckForDirectoryAndFiles()
|
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
string[] filePaths;
|
|
|
|
|
|
|
|
|
|
if (!Directory.Exists("clientside"))
|
|
|
|
|
{
|
|
|
|
|
AnyFileExists = false;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-04-02 19:12:15 +02:00
|
|
|
|
|
2022-04-03 02:27:30 +02:00
|
|
|
|
filePaths = Directory.GetFiles("clientside");
|
|
|
|
|
if (filePaths.Length == 0)
|
2022-04-02 23:02:49 +02:00
|
|
|
|
{
|
|
|
|
|
AnyFileExists = false;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-03 02:27:30 +02:00
|
|
|
|
byte fileCount = 0;
|
|
|
|
|
|
2022-04-02 23:02:49 +02:00
|
|
|
|
foreach (string file in filePaths)
|
2022-04-02 19:12:15 +02:00
|
|
|
|
{
|
|
|
|
|
FileInfo fileInfo = new(file);
|
|
|
|
|
|
|
|
|
|
// ONLY JAVASCRIPT AND JSON FILES!
|
|
|
|
|
if (!new string[] { ".js", ".json" }.Any(x => x == fileInfo.Extension))
|
|
|
|
|
{
|
2022-04-02 23:02:49 +02:00
|
|
|
|
Logging.Warning("Only files with \"*.js\" and \"*.json\" can be sent!");
|
2022-04-02 19:12:15 +02:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-03 02:27:30 +02:00
|
|
|
|
int MAX_BUFFER = fileInfo.Length < 5120 ? (int)fileInfo.Length : 5120; // 5KB
|
2022-04-02 19:12:15 +02:00
|
|
|
|
byte[] buffer = new byte[MAX_BUFFER];
|
|
|
|
|
bool fileCreated = false;
|
|
|
|
|
DownloadFile newFile = null;
|
|
|
|
|
|
|
|
|
|
using (FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read))
|
|
|
|
|
using (BufferedStream bs = new(fs))
|
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
while (bs.Read(buffer, 0, MAX_BUFFER) != 0) // Reading 5KB chunks at time
|
2022-04-02 19:12:15 +02:00
|
|
|
|
{
|
|
|
|
|
if (!fileCreated)
|
|
|
|
|
{
|
|
|
|
|
newFile = new() { FileID = fileCount, FileName = fileInfo.Name, FileLength = fileInfo.Length };
|
|
|
|
|
fileCreated = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newFile.AddData(buffer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-02 23:02:49 +02:00
|
|
|
|
_files.Add(newFile);
|
2022-04-03 02:27:30 +02:00
|
|
|
|
fileCount++;
|
2022-04-02 19:12:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-02 23:02:49 +02:00
|
|
|
|
Logging.Info($"{_files.Count} files found!");
|
|
|
|
|
|
|
|
|
|
AnyFileExists = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Tick()
|
|
|
|
|
{
|
|
|
|
|
_clients.ForEach(client =>
|
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
if (!client.SendFiles())
|
2022-04-02 23:02:49 +02:00
|
|
|
|
{
|
|
|
|
|
Client x = Server.Clients.FirstOrDefault(x => x.NetHandle == client.NetHandle);
|
|
|
|
|
if (x != null)
|
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
x.FilesReceived = true;
|
2022-04-02 23:02:49 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
2022-04-02 19:12:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-02 23:02:49 +02:00
|
|
|
|
public static void RemoveClient(long nethandle)
|
2022-04-02 19:12:15 +02:00
|
|
|
|
{
|
2022-04-02 23:02:49 +02:00
|
|
|
|
DownloadClient client = _clients.FirstOrDefault(x => x.NetHandle == nethandle);
|
|
|
|
|
if (client != null)
|
|
|
|
|
{
|
|
|
|
|
_clients.Remove(client);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-04-03 02:27:30 +02:00
|
|
|
|
|
|
|
|
|
/// <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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-04-02 23:02:49 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal class DownloadClient
|
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-04-02 23:02:49 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>true if files should be sent otherwise false</returns>
|
2022-04-03 02:27:30 +02:00
|
|
|
|
public bool SendFiles()
|
2022-04-02 23:02:49 +02:00
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
if (DownloadComplete())
|
2022-04-02 19:12:15 +02:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-03 02:27:30 +02:00
|
|
|
|
DownloadFile file = Files[FilePosition];
|
2022-04-02 23:02:49 +02:00
|
|
|
|
|
|
|
|
|
file.Send(NetHandle);
|
|
|
|
|
|
|
|
|
|
if (file.DownloadFinished())
|
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
FilePosition++;
|
2022-04-02 23:02:49 +02:00
|
|
|
|
|
2022-04-03 02:27:30 +02:00
|
|
|
|
return DownloadComplete();
|
2022-04-02 23:02:49 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-02 19:12:15 +02:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-04-03 02:27:30 +02:00
|
|
|
|
|
|
|
|
|
public bool DownloadComplete()
|
|
|
|
|
{
|
|
|
|
|
return FilePosition >= Files.Count;
|
|
|
|
|
}
|
2022-04-02 19:12:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal class DownloadFile
|
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
public byte FileID { get; set; }
|
2022-04-02 19:12:15 +02:00
|
|
|
|
public string FileName { get; set; }
|
|
|
|
|
public long FileLength { get; set; }
|
|
|
|
|
|
2022-04-02 23:02:49 +02:00
|
|
|
|
private readonly List<byte[]> _data = new();
|
2022-04-03 02:27:30 +02:00
|
|
|
|
private int _dataPosition = 0;
|
2022-04-02 19:12:15 +02:00
|
|
|
|
|
2022-04-02 23:02:49 +02:00
|
|
|
|
public void Send(long nethandle)
|
2022-04-02 19:12:15 +02:00
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
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++;
|
2022-04-02 19:12:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddData(byte[] data)
|
|
|
|
|
{
|
|
|
|
|
_data.Add(data);
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-03 02:27:30 +02:00
|
|
|
|
public void Cancel()
|
|
|
|
|
{
|
|
|
|
|
_dataPosition = _data.Count - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-02 19:12:15 +02:00
|
|
|
|
public bool DownloadFinished()
|
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
return _dataPosition >= _data.Count;
|
2022-04-02 19:12:15 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|