mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Merge pull request #153 from wabbajack-tools/manual-download-guidence
Manual Download Guidence
This commit is contained in:
commit
4d68a0c5cb
@ -103,17 +103,25 @@ namespace Wabbajack.Common
|
||||
return sha.Hash.ToBase64();
|
||||
}
|
||||
|
||||
public static string FileHash(this string file)
|
||||
public static string FileHash(this string file, bool nullOnIOError = false)
|
||||
{
|
||||
var hash = new xxHashConfig();
|
||||
hash.HashSizeInBits = 64;
|
||||
hash.Seed = 0x42;
|
||||
using (var fs = File.OpenRead(file))
|
||||
try
|
||||
{
|
||||
var config = new xxHashConfig();
|
||||
config.HashSizeInBits = 64;
|
||||
var value = xxHashFactory.Instance.Create(config).ComputeHash(fs);
|
||||
return value.AsBase64String();
|
||||
var hash = new xxHashConfig();
|
||||
hash.HashSizeInBits = 64;
|
||||
hash.Seed = 0x42;
|
||||
using (var fs = File.OpenRead(file))
|
||||
{
|
||||
var config = new xxHashConfig();
|
||||
config.HashSizeInBits = 64;
|
||||
var value = xxHashFactory.Instance.Create(config).ComputeHash(fs);
|
||||
return value.AsBase64String();
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
if (nullOnIOError) return null;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,8 @@ namespace Wabbajack.Lib.Downloaders
|
||||
new ModDBDownloader(),
|
||||
new NexusDownloader(),
|
||||
new MediaFireDownloader(),
|
||||
new HTTPDownloader(),
|
||||
new ManualDownloader(),
|
||||
new HTTPDownloader()
|
||||
};
|
||||
|
||||
private static readonly Dictionary<Type, IDownloader> IndexedDownloaders;
|
||||
|
@ -1,15 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using System.Reactive.Threading.Tasks;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Syroot.Windows.IO;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Lib.Validation;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
class ManualDownloader : IDownloader
|
||||
public class ManualDownloader : IDownloader
|
||||
{
|
||||
private FileSystemWatcher _watcher;
|
||||
private Subject<FileEvent> _fileEvents = new Subject<FileEvent>();
|
||||
private KnownFolder _downloadfolder;
|
||||
|
||||
class FileEvent
|
||||
{
|
||||
public string FullPath { get; set; }
|
||||
public string Name { get; set; }
|
||||
public long Size { get; set; }
|
||||
}
|
||||
|
||||
public ManualDownloader()
|
||||
{
|
||||
_downloadfolder = new KnownFolder(KnownFolderType.DownloadsLocalized);
|
||||
_watcher = new FileSystemWatcher(_downloadfolder.Path);
|
||||
_watcher.Created += _watcher_Created;
|
||||
_watcher.Changed += _watcher_Changed;
|
||||
}
|
||||
|
||||
private void _watcher_Changed(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
PublishEvent(e);
|
||||
}
|
||||
private void _watcher_Created(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
PublishEvent(e);
|
||||
}
|
||||
|
||||
private void PublishEvent(FileSystemEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_fileEvents.OnNext(new FileEvent
|
||||
{
|
||||
Size = new FileInfo(e.FullPath).Length,
|
||||
Name = e.Name,
|
||||
FullPath = e.FullPath
|
||||
});
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public AbstractDownloadState GetDownloaderState(dynamic archive_ini)
|
||||
{
|
||||
var url = archive_ini?.General?.manualURL;
|
||||
@ -30,7 +82,33 @@ namespace Wabbajack.Lib.Downloaders
|
||||
|
||||
public override void Download(Archive a, string destination)
|
||||
{
|
||||
Utils.Log($"You must manually visit {Url} and download {a.Name} file by hand.");
|
||||
var downloader = (ManualDownloader)GetDownloader();
|
||||
var abs_path = Path.Combine(downloader._downloadfolder.Path, a.Name);
|
||||
lock (downloader)
|
||||
{
|
||||
try
|
||||
{
|
||||
Utils.Log($"You must manually visit {Url} and download {a.Name} file by hand.");
|
||||
Utils.Log($"Waiting for {a.Name}");
|
||||
downloader._watcher.EnableRaisingEvents = true;
|
||||
var watcher = downloader._fileEvents
|
||||
.Where(f => f.Size == a.Size)
|
||||
.Where(f => f.FullPath.FileHash(true) == a.Hash)
|
||||
.Buffer(new TimeSpan(0, 5, 0), 1)
|
||||
.Select(x => x.FirstOrDefault())
|
||||
.FirstOrDefaultAsync();
|
||||
Process.Start(Url);
|
||||
|
||||
abs_path = watcher.Wait()?.FullPath;
|
||||
if (!File.Exists(abs_path))
|
||||
throw new InvalidDataException($"File not found after manual download operation");
|
||||
File.Move(abs_path, destination);
|
||||
}
|
||||
finally
|
||||
{
|
||||
downloader._watcher.EnableRaisingEvents = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Verify()
|
||||
|
@ -229,19 +229,6 @@ namespace Wabbajack.Lib
|
||||
Info("Done! You may now exit the application!");
|
||||
}
|
||||
|
||||
private bool LocateGameFolder()
|
||||
{
|
||||
var fs = UIUtils.ShowFolderSelectionDialog("Please locate your game installation path");
|
||||
if (fs != null)
|
||||
{
|
||||
GameFolder = fs;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// We don't want to make the installer index all the archives, that's just a waste of time, so instead
|
||||
/// we'll pass just enough information to VFS to let it know about the files we have.
|
||||
@ -457,17 +444,27 @@ namespace Wabbajack.Lib
|
||||
|
||||
Info("Getting Nexus API Key, if a browser appears, please accept");
|
||||
|
||||
var dispatchers = ModList.Archives.Select(m => m.State.GetDownloader()).Distinct();
|
||||
var dispatchers = missing.Select(m => m.State.GetDownloader()).Distinct();
|
||||
|
||||
foreach (var dispatcher in dispatchers)
|
||||
dispatcher.Prepare();
|
||||
|
||||
|
||||
DownloadMissingArchives(missing);
|
||||
}
|
||||
|
||||
private void DownloadMissingArchives(List<Archive> missing, bool download = true)
|
||||
{
|
||||
missing.PMap(archive =>
|
||||
if (download)
|
||||
{
|
||||
foreach (var a in missing.Where(a => a.State.GetType() == typeof(ManualDownloader.State)))
|
||||
{
|
||||
var output_path = Path.Combine(DownloadFolder, a.Name);
|
||||
a.State.Download(a, output_path);
|
||||
}
|
||||
}
|
||||
|
||||
missing.Where(a => a.State.GetType() != typeof(ManualDownloader.State))
|
||||
.PMap(archive =>
|
||||
{
|
||||
Info($"Downloading {archive.Name}");
|
||||
var output_path = Path.Combine(DownloadFolder, archive.Name);
|
||||
|
@ -54,6 +54,9 @@
|
||||
<ItemGroup>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="Syroot.KnownFolders">
|
||||
<HintPath>..\..\..\Users\tbald\.nuget\packages\syroot.windows.io.knownfolders\1.2.1\lib\net452\Syroot.KnownFolders.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Design" />
|
||||
@ -186,6 +189,9 @@
|
||||
<PackageReference Include="SharpCompress">
|
||||
<Version>0.23.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Syroot.Windows.IO.KnownFolders">
|
||||
<Version>1.2.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Reactive">
|
||||
<Version>4.2.0</Version>
|
||||
</PackageReference>
|
||||
|
@ -147,6 +147,29 @@ namespace Wabbajack.Test
|
||||
Assert.AreEqual(File.ReadAllText(filename), "Cheese for Everyone!");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ManualDownload()
|
||||
{
|
||||
var ini = @"[General]
|
||||
manualURL=http://build.wabbajack.org/WABBAJACK_TEST_FILE.zip";
|
||||
|
||||
var state = (AbstractDownloadState)DownloadDispatcher.ResolveArchive(ini.LoadIniString());
|
||||
|
||||
Assert.IsNotNull(state);
|
||||
|
||||
var converted = state.ViaJSON();
|
||||
Assert.IsTrue(converted.Verify());
|
||||
var filename = Guid.NewGuid().ToString();
|
||||
|
||||
Assert.IsTrue(converted.IsWhitelisted(new ServerWhitelist { AllowedPrefixes = new List<string> { "http://build.wabbajack.org/" } }));
|
||||
|
||||
converted.Download(new Archive { Name = "WABBAJACK_TEST_FILE.zip", Size = 20, Hash = "eSIyd+KOG3s="}, filename);
|
||||
|
||||
Assert.AreEqual("eSIyd+KOG3s=", Utils.FileHash(filename));
|
||||
|
||||
Assert.AreEqual(File.ReadAllText(filename), "Cheese for Everyone!");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MediaFireDownload()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user