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();
|
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();
|
try
|
||||||
hash.HashSizeInBits = 64;
|
|
||||||
hash.Seed = 0x42;
|
|
||||||
using (var fs = File.OpenRead(file))
|
|
||||||
{
|
{
|
||||||
var config = new xxHashConfig();
|
var hash = new xxHashConfig();
|
||||||
config.HashSizeInBits = 64;
|
hash.HashSizeInBits = 64;
|
||||||
var value = xxHashFactory.Instance.Create(config).ComputeHash(fs);
|
hash.Seed = 0x42;
|
||||||
return value.AsBase64String();
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Reactive.Subjects;
|
||||||
|
using System.Reactive.Threading.Tasks;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Syroot.Windows.IO;
|
||||||
using Wabbajack.Common;
|
using Wabbajack.Common;
|
||||||
using Wabbajack.Lib.Validation;
|
using Wabbajack.Lib.Validation;
|
||||||
|
using File = System.IO.File;
|
||||||
|
|
||||||
namespace Wabbajack.Lib.Downloaders
|
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)
|
public AbstractDownloadState GetDownloaderState(dynamic archive_ini)
|
||||||
{
|
{
|
||||||
var url = archive_ini?.General?.manualURL;
|
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 class State : AbstractDownloadState
|
||||||
{
|
{
|
||||||
public string Url { get; set; }
|
public string Url { get; set; }
|
||||||
@ -30,7 +90,32 @@ namespace Wabbajack.Lib.Downloaders
|
|||||||
|
|
||||||
public override void Download(Archive a, string destination)
|
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()
|
public override bool Verify()
|
||||||
|
@ -229,19 +229,6 @@ namespace Wabbajack.Lib
|
|||||||
Info("Done! You may now exit the application!");
|
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>
|
/// <summary>
|
||||||
/// We don't want to make the installer index all the archives, that's just a waste of time, so instead
|
/// 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.
|
/// we'll pass just enough information to VFS to let it know about the files we have.
|
||||||
|
@ -54,6 +54,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<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" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Design" />
|
<Reference Include="System.Design" />
|
||||||
@ -186,6 +189,9 @@
|
|||||||
<PackageReference Include="SharpCompress">
|
<PackageReference Include="SharpCompress">
|
||||||
<Version>0.23.0</Version>
|
<Version>0.23.0</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Syroot.Windows.IO.KnownFolders">
|
||||||
|
<Version>1.2.1</Version>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="System.Reactive">
|
<PackageReference Include="System.Reactive">
|
||||||
<Version>4.2.0</Version>
|
<Version>4.2.0</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
@ -147,6 +147,34 @@ namespace Wabbajack.Test
|
|||||||
Assert.AreEqual(File.ReadAllText(filename), "Cheese for Everyone!");
|
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]
|
[TestMethod]
|
||||||
public void MediaFireDownload()
|
public void MediaFireDownload()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user