Merge remote-tracking branch 'origin/master'

This commit is contained in:
Timothy Baldridge 2021-02-03 20:54:12 -07:00
commit ec8d0afcb8
10 changed files with 119 additions and 13 deletions

View File

@ -575,6 +575,7 @@ namespace Wabbajack.Common
MO2Name = "Dragon Age: Origins", // Probably wrong
SteamIDs = new List<int>{47810},
OriginIDs = new List<string>{"DR:208591800"},
GOGIDs = new List<int>{1949616134},
RequiredFiles = new List<string>
{
@"bin_ship\daorigins.exe"

View File

@ -0,0 +1,64 @@
using System;
using System.Linq;
using System.Management;
namespace Wabbajack.Common
{
public class PhysicalDisk
{
public PhysicalDisk(string driveLetter)
{
if (driveLetter.Length == 2 && driveLetter[1] == ':') driveLetter = driveLetter.Remove(driveLetter.Length - 1);
if (driveLetter.Length == 3 && (driveLetter[1] == ':' && driveLetter[2] == '\\')) driveLetter = driveLetter.Remove(driveLetter.Length - 2);
if (driveLetter.Length > 3) Utils.Error("Incorrect drive name! Must be X, X: or X:\\");
Utils.Log($"Phsyical Disk: {driveLetter}");
// Connect to storage scope
var scope = new ManagementScope(@"\\.\root\microsoft\windows\storage");
scope.Connect();
// Search partitions that use requested the drive letter
var partitionSearcher = new ManagementObjectSearcher($"SELECT DiskNumber FROM MSFT_Partition WHERE DriveLetter='{driveLetter}'");
partitionSearcher.Scope = scope;
// Get first partition that matches
var partition = partitionSearcher.Get().OfType<ManagementObject>().First();
// Search for a disk where the device ID matches the one we got from the partition
var physicalSearcher = new ManagementObjectSearcher($"SELECT * FROM MSFT_PhysicalDisk WHERE DeviceId='{partition["DiskNumber"]}'");
physicalSearcher.Scope = scope;
// Get disk information
var physical = physicalSearcher.Get().Cast<ManagementBaseObject>().Single();
DriveLetter = driveLetter;
DeviceId = (string)physical["DeviceId"];
MediaType = (MediaTypes)Convert.ToInt32(physical["MediaType"]);
BusType = (BusTypes)Convert.ToInt32(physical["BusType"]);
}
public string DriveLetter { get; }
public string DeviceId { get; }
public MediaTypes MediaType { get; }
public BusTypes BusType { get; }
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/stormgmt/msft-physicaldisk#properties
public enum MediaTypes
{
Unspecified = 0,
HDD = 3,
SSD = 4,
SCM = 5
}
public enum BusTypes
{
Unknown = 0,
USB = 7,
SATA = 11,
NVMe = 17
}
}
}

View File

@ -57,6 +57,7 @@
<PackageReference Include="SharpZipLib" Version="1.3.1" />
<PackageReference Include="System.Data.HashFunction.xxHash" Version="2.0.0" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.113.7" />
<PackageReference Include="System.Management" Version="5.0.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="5.0.0" />

View File

@ -15,8 +15,9 @@ namespace Wabbajack.Lib
{
public WorkQueue Queue { get; } = new WorkQueue();
public int DownloadThreads { get; set; } = Environment.ProcessorCount;
public int DownloadThreads { get; set; } = Environment.ProcessorCount <= 8 ? Environment.ProcessorCount : 8;
public int DiskThreads { get; set; } = Environment.ProcessorCount;
public bool ReduceHDDThreads { get; set; } = true;
public bool FavorPerfOverRam { get; set; } = false;
public Context VFS { get; }

View File

@ -114,6 +114,7 @@ namespace Wabbajack.Lib
public async Task InstallArchives()
{
var grouped = ModList.Directives
.OfType<FromArchive>()
.Select(a => new {VF = VFS.Index.FileForArchiveHashPath(a.ArchiveHashPath), Directive = a})
@ -218,8 +219,6 @@ namespace Wabbajack.Lib
}
}
DesiredThreads.OnNext(DownloadThreads);
await missing.Where(a => a.State.GetType() != typeof(ManualDownloader.State))
.PMap(Queue, UpdateTracker, async archive =>
{
@ -240,9 +239,6 @@ namespace Wabbajack.Lib
return await DownloadArchive(archive, download, outputPath);
});
DesiredThreads.OnNext(DiskThreads);
}
private async Task SendDownloadMetrics(List<Archive> missing)
@ -289,7 +285,7 @@ namespace Wabbajack.Lib
var toHash = ModList.Archives.Where(a => hashDict.ContainsKey(a.Size)).SelectMany(a => hashDict[a.Size]).ToList();
Utils.Log($"Found {allFiles.Count} total files, {toHash.Count} matching filesize");
var hashResults = await
toHash
.PMap(Queue, UpdateTracker,async e => (await e.FileHashCachedAsync(), e));

View File

@ -56,7 +56,8 @@ namespace Wabbajack.Lib
await Metrics.Send(Metrics.BeginInstall, ModList.Name);
Utils.Log("Configuring Processor");
DesiredThreads.OnNext(DiskThreads);
if (new PhysicalDisk(OutputFolder.DriveInfo().Name).MediaType == PhysicalDisk.MediaTypes.HDD && ReduceHDDThreads) DesiredThreads.OnNext(1); else DesiredThreads.OnNext(DiskThreads);
FileExtractor2.FavorPerfOverRAM = FavorPerfOverRam;
if (GameFolder == null)
@ -123,14 +124,23 @@ namespace Wabbajack.Lib
UpdateTracker.NextStep("Optimizing ModList");
await OptimizeModlist();
// Reduce to one thread if downloads on HDD, else use specified. Hashing on HDD has no benefit with more threads.
if (new PhysicalDisk(DownloadFolder.DriveInfo().Name).MediaType == PhysicalDisk.MediaTypes.HDD && ReduceHDDThreads) DesiredThreads.OnNext(1); else DesiredThreads.OnNext(DiskThreads);
if (cancel.IsCancellationRequested) return false;
UpdateTracker.NextStep("Hashing Archives");
await HashArchives();
// Set to download thread count.
DesiredThreads.OnNext(DownloadThreads);
if (cancel.IsCancellationRequested) return false;
UpdateTracker.NextStep("Downloading Missing Archives");
await DownloadArchives();
// Reduce to one thread if downloads on HDD, else use specified. Hashing on HDD has no benefit with more threads.
if (new PhysicalDisk(DownloadFolder.DriveInfo().Name).MediaType == PhysicalDisk.MediaTypes.HDD && ReduceHDDThreads) DesiredThreads.OnNext(1); else DesiredThreads.OnNext(DiskThreads);
if (cancel.IsCancellationRequested) return false;
UpdateTracker.NextStep("Hashing Remaining Archives");
await HashArchives();
@ -146,6 +156,9 @@ namespace Wabbajack.Lib
Error("Cannot continue, was unable to download one or more archives");
}
// Reduce to two threads if output on HDD, else use specified. Installing files seems to have a slight benefit with two threads.
if (new PhysicalDisk(OutputFolder.DriveInfo().Name).MediaType == PhysicalDisk.MediaTypes.HDD && ReduceHDDThreads) DesiredThreads.OnNext(2); else DesiredThreads.OnNext(DiskThreads);
if (cancel.IsCancellationRequested) return false;
UpdateTracker.NextStep("Extracting Modlist contents");
await ExtractModlist();

View File

@ -116,9 +116,10 @@ namespace Wabbajack
{
public PerformanceSettings()
{
_reduceHDDThreads = true;
_favorPerfOverRam = false;
_diskThreads = Environment.ProcessorCount;
_downloadThreads = Environment.ProcessorCount;
_downloadThreads = Environment.ProcessorCount <= 8 ? Environment.ProcessorCount : 8;
}
private int _downloadThreads;
@ -126,7 +127,10 @@ namespace Wabbajack
private int _diskThreads;
public int DiskThreads { get => _diskThreads; set => RaiseAndSetIfChanged(ref _diskThreads, value); }
private bool _reduceHDDThreads;
public bool ReduceHDDThreads { get => _reduceHDDThreads; set => RaiseAndSetIfChanged(ref _reduceHDDThreads, value); }
private bool _favorPerfOverRam;
public bool FavorPerfOverRam { get => _favorPerfOverRam; set => RaiseAndSetIfChanged(ref _favorPerfOverRam, value); }
@ -135,6 +139,7 @@ namespace Wabbajack
{
processor.DownloadThreads = DownloadThreads;
processor.DiskThreads = DiskThreads;
processor.ReduceHDDThreads = ReduceHDDThreads;
processor.FavorPerfOverRam = FavorPerfOverRam;
}
}

View File

@ -76,18 +76,30 @@ namespace Wabbajack
})
.ToProperty(this, nameof(CanInstall));
// Have Installation location updates modify the downloads location if empty
// Have Installation location updates modify the downloads location if empty or the same path
this.WhenAny(x => x.Location.TargetPath)
.Skip(1) // Don't do it initially
.Subscribe(installPath =>
{
if (DownloadLocation.TargetPath == default)
if (DownloadLocation.TargetPath == default || DownloadLocation.TargetPath == installPath)
{
DownloadLocation.TargetPath = installPath.Combine("downloads");
}
})
.DisposeWith(CompositeDisposable);
// Have Download location updates change if the same as the install path
this.WhenAny(x => x.DownloadLocation.TargetPath)
.Skip(1) // Don't do it initially
.Subscribe(downloadPath =>
{
if (downloadPath == Location.TargetPath)
{
DownloadLocation.TargetPath = Location.TargetPath.Combine("downloads");
}
})
.DisposeWith(CompositeDisposable);
// Load settings
_CurrentSettings = installerVM.WhenAny(x => x.ModListLocation.TargetPath)
.Select(path => path == default ? null : installerVM.MWVM.Settings.Installer.Mo2ModlistSettings.TryCreate(path))

View File

@ -26,6 +26,7 @@
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
@ -67,10 +68,20 @@
Maximum="128"
Minimum="2" />
<TextBlock Grid.Row="5" Grid.Column="0"
x:Name="ReduceHDDThreadsLabel"
VerticalAlignment="Center"
Text="Reduce HDD threads (Recommended)" />
<CheckBox Grid.Row="5" Grid.Column="2"
x:Name="ReduceHDDThreads"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Foreground="White"
></CheckBox>
<TextBlock Grid.Row="6" Grid.Column="0"
x:Name="FavorPerfOverRamLabel"
VerticalAlignment="Center"
Text="Favor performance over RAM Usage" />
<CheckBox Grid.Row="5" Grid.Column="2"
<CheckBox Grid.Row="6" Grid.Column="2"
x:Name="FavorPerfOverRam"
HorizontalAlignment="Right"
VerticalAlignment="Center"

View File

@ -39,6 +39,8 @@ namespace Wabbajack
vmToViewConverter: x => x,
viewToVmConverter: x => (int)(x ?? 0))
.DisposeWith(disposable);
this.BindStrict(this.ViewModel, x => x.ReduceHDDThreads, x => x.ReduceHDDThreads.IsChecked)
.DisposeWith(disposable);
this.BindStrict(this.ViewModel, x => x.FavorPerfOverRam, x => x.FavorPerfOverRam.IsChecked)
.DisposeWith(disposable);
});