2022-04-02 18:11:30 +02:00
|
|
|
|
using System.IO;
|
2022-04-06 05:10:29 +02:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Collections.Generic;
|
2022-04-02 16:40:24 +02:00
|
|
|
|
|
|
|
|
|
namespace CoopClient
|
|
|
|
|
{
|
2022-04-06 05:10:29 +02:00
|
|
|
|
internal static class DownloadManager
|
2022-04-02 16:40:24 +02:00
|
|
|
|
{
|
2022-04-06 05:10:29 +02:00
|
|
|
|
private static readonly List<DownloadFile> _downloadFiles = new List<DownloadFile>();
|
|
|
|
|
private static readonly Dictionary<byte, FileStream> _streams = new Dictionary<byte, FileStream>();
|
|
|
|
|
private static readonly List<byte> _filesFinished = new List<byte>();
|
2022-04-06 05:54:03 +02:00
|
|
|
|
public static bool DownloadComplete = false;
|
2022-04-02 16:40:24 +02:00
|
|
|
|
|
2022-04-06 05:10:29 +02:00
|
|
|
|
public static void AddFile(byte id, Packets.DataFileType type, string name, long length)
|
2022-04-02 16:40:24 +02:00
|
|
|
|
{
|
2022-04-03 02:27:30 +02:00
|
|
|
|
string downloadFolder = $"scripts\\resources\\{Main.MainSettings.LastServerAddress.Replace(":", ".")}";
|
2022-04-06 05:10:29 +02:00
|
|
|
|
|
2022-04-02 18:11:30 +02:00
|
|
|
|
if (!Directory.Exists(downloadFolder))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(downloadFolder);
|
2022-04-06 05:10:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FileAlreadyExists(downloadFolder, name, length))
|
|
|
|
|
{
|
|
|
|
|
// Send the server we are already done
|
|
|
|
|
Main.MainNetworking.SendDownloadFinish(id);
|
|
|
|
|
|
|
|
|
|
lock (_filesFinished)
|
2022-04-02 18:11:30 +02:00
|
|
|
|
{
|
2022-04-06 05:10:29 +02:00
|
|
|
|
_filesFinished.Add(id);
|
2022-04-02 18:11:30 +02:00
|
|
|
|
}
|
2022-04-06 05:10:29 +02:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lock (_downloadFiles)
|
|
|
|
|
{
|
|
|
|
|
_downloadFiles.Add(new DownloadFile()
|
|
|
|
|
{
|
|
|
|
|
FileID = id,
|
|
|
|
|
FileType = type,
|
|
|
|
|
FileName = name,
|
|
|
|
|
FileLength = length
|
|
|
|
|
});
|
2022-04-02 18:11:30 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-06 05:10:29 +02:00
|
|
|
|
lock (_streams)
|
|
|
|
|
{
|
2022-04-06 08:44:17 +02:00
|
|
|
|
_streams.Add(id, new FileStream($"{downloadFolder}\\{name}", FileMode.CreateNew, FileAccess.Write, FileShare.ReadWrite));
|
2022-04-06 05:10:29 +02:00
|
|
|
|
}
|
2022-04-02 16:40:24 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-02 18:11:30 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Check if the file already exists and if the size correct otherwise delete this file
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="folder"></param>
|
2022-04-06 05:10:29 +02:00
|
|
|
|
/// <param name="name"></param>
|
|
|
|
|
/// <param name="length"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private static bool FileAlreadyExists(string folder, string name, long length)
|
2022-04-02 16:40:24 +02:00
|
|
|
|
{
|
2022-04-06 05:10:29 +02:00
|
|
|
|
string filePath = $"{folder}\\{name}";
|
|
|
|
|
|
2022-04-02 18:11:30 +02:00
|
|
|
|
if (File.Exists(filePath))
|
|
|
|
|
{
|
2022-04-06 05:10:29 +02:00
|
|
|
|
if (new FileInfo(filePath).Length == length)
|
2022-04-02 18:11:30 +02:00
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-04-06 05:10:29 +02:00
|
|
|
|
|
|
|
|
|
// Delete the file because the length is wrong (maybe the file was updated)
|
|
|
|
|
File.Delete(filePath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Write(byte id, byte[] data)
|
|
|
|
|
{
|
|
|
|
|
lock (_filesFinished)
|
|
|
|
|
{
|
|
|
|
|
if (_filesFinished.Contains(id))
|
2022-04-02 18:11:30 +02:00
|
|
|
|
{
|
2022-04-06 05:10:29 +02:00
|
|
|
|
Cancel(id);
|
|
|
|
|
return;
|
2022-04-02 18:11:30 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-04-02 16:40:24 +02:00
|
|
|
|
|
2022-04-06 05:10:29 +02:00
|
|
|
|
lock (_streams)
|
|
|
|
|
{
|
2022-04-06 08:44:17 +02:00
|
|
|
|
FileStream fs = _streams.FirstOrDefault(x => x.Key == id).Value;
|
2022-04-06 05:10:29 +02:00
|
|
|
|
if (fs == null)
|
|
|
|
|
{
|
2022-04-06 08:44:17 +02:00
|
|
|
|
Logger.Write($"Stream for file {id} not found!", Logger.LogLevel.Server);
|
|
|
|
|
return;
|
2022-04-06 05:10:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fs.Write(data, 0, data.Length);
|
|
|
|
|
|
|
|
|
|
lock (_downloadFiles)
|
|
|
|
|
{
|
|
|
|
|
DownloadFile file = _downloadFiles.FirstOrDefault(x => x.FileID == id);
|
|
|
|
|
if (file == null)
|
|
|
|
|
{
|
2022-04-06 08:44:17 +02:00
|
|
|
|
Logger.Write($"File {id} couldn't be found in the list!", Logger.LogLevel.Server);
|
|
|
|
|
return;
|
2022-04-06 05:10:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-06 06:52:02 +02:00
|
|
|
|
file.FileWritten += data.Length;
|
|
|
|
|
|
|
|
|
|
if (file.FileWritten >= file.FileLength)
|
2022-04-06 05:10:29 +02:00
|
|
|
|
{
|
|
|
|
|
Cancel(id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Cancel(byte id)
|
|
|
|
|
{
|
|
|
|
|
lock (_streams) lock (_downloadFiles)
|
|
|
|
|
{
|
|
|
|
|
FileStream fs = _streams.ContainsKey(id) ? _streams[id] : null;
|
|
|
|
|
if (fs != null)
|
|
|
|
|
{
|
|
|
|
|
fs.Close();
|
|
|
|
|
fs.Dispose();
|
|
|
|
|
|
|
|
|
|
_streams.Remove(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_downloadFiles.Any(x => x.FileID == id))
|
|
|
|
|
{
|
|
|
|
|
_downloadFiles.Remove(_downloadFiles.First(x => x.FileID == id));
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-04-02 18:11:30 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-06 08:44:17 +02:00
|
|
|
|
public static void Cleanup(bool everything)
|
2022-04-02 18:11:30 +02:00
|
|
|
|
{
|
2022-04-06 05:10:29 +02:00
|
|
|
|
lock (_streams) lock (_downloadFiles) lock (_filesFinished)
|
2022-04-02 18:11:30 +02:00
|
|
|
|
{
|
2022-04-06 08:44:17 +02:00
|
|
|
|
foreach (KeyValuePair<byte, FileStream> stream in _streams)
|
2022-04-06 05:10:29 +02:00
|
|
|
|
{
|
|
|
|
|
stream.Value.Close();
|
|
|
|
|
stream.Value.Dispose();
|
|
|
|
|
}
|
|
|
|
|
_streams.Clear();
|
|
|
|
|
_downloadFiles.Clear();
|
|
|
|
|
_filesFinished.Clear();
|
2022-04-02 18:11:30 +02:00
|
|
|
|
}
|
2022-04-06 05:54:03 +02:00
|
|
|
|
|
2022-04-06 08:44:17 +02:00
|
|
|
|
if (everything)
|
|
|
|
|
{
|
|
|
|
|
DownloadComplete = false;
|
|
|
|
|
}
|
2022-04-02 16:40:24 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-04-06 05:10:29 +02:00
|
|
|
|
|
|
|
|
|
internal class DownloadFile
|
|
|
|
|
{
|
|
|
|
|
public byte FileID { get; set; } = 0;
|
|
|
|
|
public Packets.DataFileType FileType { get; set; } = Packets.DataFileType.Script;
|
|
|
|
|
public string FileName { get; set; } = string.Empty;
|
|
|
|
|
public long FileLength { get; set; } = 0;
|
2022-04-06 06:52:02 +02:00
|
|
|
|
public long FileWritten { get; set; } = 0;
|
2022-04-06 05:10:29 +02:00
|
|
|
|
}
|
2022-04-02 16:40:24 +02:00
|
|
|
|
}
|