mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
a87f8dac7f
* added enderalse GOGID * Fix readme opening twice when loading last modlist * Edit Wabbajack CLI button text * Cancel running downloads when shutting down application * Add resume support for IHttpDownloader * Add resume support for manual downloads * Update CHANGELOG.md * Improve game selection to only show games with results combined with the amount of lists * Undo accidental removal of loading settings * Add more tooltips and improve existing ones * Update CHANGELOG.md * Main test external pull readme fix (#2335) * Fix SelectedGameType crashing Wabbajack when no settings are present yet, fix readme being clickable when not specified resulting in crash * Add readme fix to CHANGELOG, fix typo * Add readme button fix to changelog --------- Co-authored-by: UrbanCMC <UrbanCMC@web.de> Co-authored-by: Angad <angadmisra28@gmail.com> Co-authored-by: trawzified <55751269+tr4wzified@users.noreply.github.com> Co-authored-by: Timothy Baldridge <tbaldridge@gmail.com>
97 lines
3.4 KiB
C#
97 lines
3.4 KiB
C#
using System;
|
|
using System.Reactive.Subjects;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Logging;
|
|
using Wabbajack.Common;
|
|
using Wabbajack.Downloaders;
|
|
using Wabbajack.DTOs;
|
|
using Wabbajack.DTOs.JsonConverters;
|
|
using Wabbajack.Paths;
|
|
using Wabbajack.Paths.IO;
|
|
using Wabbajack.RateLimiter;
|
|
using Wabbajack.VFS;
|
|
|
|
namespace Wabbajack.Services.OSIntegrated.Services;
|
|
|
|
public class ModListDownloadMaintainer
|
|
{
|
|
private readonly ILogger<ModListDownloadMaintainer> _logger;
|
|
private readonly Configuration _configuration;
|
|
private readonly DownloadDispatcher _dispatcher;
|
|
private readonly FileHashCache _hashCache;
|
|
private readonly IResource<DownloadDispatcher> _rateLimiter;
|
|
private int _downloadingCount;
|
|
private readonly DTOSerializer _dtos;
|
|
|
|
public ModListDownloadMaintainer(ILogger<ModListDownloadMaintainer> logger, Configuration configuration,
|
|
DownloadDispatcher dispatcher, FileHashCache hashCache, DTOSerializer dtos, IResource<DownloadDispatcher> rateLimiter)
|
|
{
|
|
_logger = logger;
|
|
_configuration = configuration;
|
|
_dispatcher = dispatcher;
|
|
_hashCache = hashCache;
|
|
_rateLimiter = rateLimiter;
|
|
_downloadingCount = 0;
|
|
_dtos = dtos;
|
|
}
|
|
|
|
public AbsolutePath ModListPath(ModlistMetadata metadata)
|
|
{
|
|
return _configuration.ModListsDownloadLocation.Combine(metadata.NamespacedName.Replace("/", "_@@_")).WithExtension(Ext.Wabbajack);
|
|
}
|
|
|
|
public async Task<bool> HaveModList(ModlistMetadata metadata, CancellationToken? token = null)
|
|
{
|
|
token ??= CancellationToken.None;
|
|
var path = ModListPath(metadata);
|
|
if (!path.FileExists()) return false;
|
|
|
|
if (await _hashCache.TryGetHashCache(path) == metadata.DownloadMetadata!.Hash) return true;
|
|
if (_downloadingCount > 0) return false;
|
|
|
|
return await _hashCache.FileHashCachedAsync(path, token.Value) == metadata.DownloadMetadata!.Hash;
|
|
}
|
|
|
|
public (IObservable<Percent> Progress, Task Task) DownloadModlist(ModlistMetadata metadata, CancellationToken token)
|
|
{
|
|
var path = ModListPath(metadata);
|
|
|
|
var progress = new Subject<Percent>();
|
|
progress.OnNext(Percent.Zero);
|
|
|
|
var tsk = Task.Run(async () =>
|
|
{
|
|
try
|
|
{
|
|
Interlocked.Increment(ref _downloadingCount);
|
|
using var job = await _rateLimiter.Begin($"Downloading {metadata.Title}", metadata.DownloadMetadata!.Size,
|
|
token);
|
|
|
|
job.OnUpdate += (_, pr) => { progress.OnNext(pr.Progress); };
|
|
|
|
var hash = await _dispatcher.Download(new Archive()
|
|
{
|
|
State = _dispatcher.Parse(new Uri(metadata.Links.Download))!,
|
|
Size = metadata.DownloadMetadata.Size,
|
|
Hash = metadata.DownloadMetadata.Hash
|
|
}, path, job, token);
|
|
if (token.IsCancellationRequested)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await _hashCache.FileHashWriteCache(path, hash);
|
|
await path.WithExtension(Ext.MetaData).WriteAllTextAsync(JsonSerializer.Serialize(metadata), token);
|
|
}
|
|
finally
|
|
{
|
|
progress.OnCompleted();
|
|
Interlocked.Decrement(ref _downloadingCount);
|
|
}
|
|
}, token);
|
|
|
|
return (progress, tsk);
|
|
}
|
|
} |