mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Enable guidence for users to download manual files.
This commit is contained in:
parent
3f4a2bb733
commit
e518f31a71
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 : IUrlDownloader
|
||||
{
|
||||
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;
|
||||
@ -20,6 +72,14 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
}
|
||||
|
||||
public AbstractDownloadState GetDownloaderState(string url)
|
||||
{
|
||||
return new State
|
||||
{
|
||||
Url = url
|
||||
};
|
||||
}
|
||||
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
public string Url { get; set; }
|
||||
@ -30,7 +90,32 @@ 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);
|
||||
watcher.Wait();
|
||||
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.
|
||||
|
@ -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,34 @@ 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 url_state = DownloadDispatcher.ResolveArchive("http://build.wabbajack.org/WABBAJACK_TEST_FILE.zip");
|
||||
|
||||
Assert.AreEqual("http://build.wabbajack.org/WABBAJACK_TEST_FILE.zip",
|
||||
((ManualDownloader.State)url_state).Url);
|
||||
|
||||
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