mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
ec8d0afcb8
@ -575,6 +575,7 @@ namespace Wabbajack.Common
|
|||||||
MO2Name = "Dragon Age: Origins", // Probably wrong
|
MO2Name = "Dragon Age: Origins", // Probably wrong
|
||||||
SteamIDs = new List<int>{47810},
|
SteamIDs = new List<int>{47810},
|
||||||
OriginIDs = new List<string>{"DR:208591800"},
|
OriginIDs = new List<string>{"DR:208591800"},
|
||||||
|
GOGIDs = new List<int>{1949616134},
|
||||||
RequiredFiles = new List<string>
|
RequiredFiles = new List<string>
|
||||||
{
|
{
|
||||||
@"bin_ship\daorigins.exe"
|
@"bin_ship\daorigins.exe"
|
||||||
|
64
Wabbajack.Common/Util/PhysicalDisk.cs
Normal file
64
Wabbajack.Common/Util/PhysicalDisk.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -57,6 +57,7 @@
|
|||||||
<PackageReference Include="SharpZipLib" Version="1.3.1" />
|
<PackageReference Include="SharpZipLib" Version="1.3.1" />
|
||||||
<PackageReference Include="System.Data.HashFunction.xxHash" Version="2.0.0" />
|
<PackageReference Include="System.Data.HashFunction.xxHash" Version="2.0.0" />
|
||||||
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.113.7" />
|
<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.Net.Http" Version="4.3.4" />
|
||||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="5.0.0" />
|
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="5.0.0" />
|
||||||
|
@ -15,8 +15,9 @@ namespace Wabbajack.Lib
|
|||||||
{
|
{
|
||||||
public WorkQueue Queue { get; } = new WorkQueue();
|
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 int DiskThreads { get; set; } = Environment.ProcessorCount;
|
||||||
|
public bool ReduceHDDThreads { get; set; } = true;
|
||||||
public bool FavorPerfOverRam { get; set; } = false;
|
public bool FavorPerfOverRam { get; set; } = false;
|
||||||
|
|
||||||
public Context VFS { get; }
|
public Context VFS { get; }
|
||||||
|
@ -114,6 +114,7 @@ namespace Wabbajack.Lib
|
|||||||
|
|
||||||
public async Task InstallArchives()
|
public async Task InstallArchives()
|
||||||
{
|
{
|
||||||
|
|
||||||
var grouped = ModList.Directives
|
var grouped = ModList.Directives
|
||||||
.OfType<FromArchive>()
|
.OfType<FromArchive>()
|
||||||
.Select(a => new {VF = VFS.Index.FileForArchiveHashPath(a.ArchiveHashPath), Directive = a})
|
.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))
|
await missing.Where(a => a.State.GetType() != typeof(ManualDownloader.State))
|
||||||
.PMap(Queue, UpdateTracker, async archive =>
|
.PMap(Queue, UpdateTracker, async archive =>
|
||||||
{
|
{
|
||||||
@ -240,9 +239,6 @@ namespace Wabbajack.Lib
|
|||||||
|
|
||||||
return await DownloadArchive(archive, download, outputPath);
|
return await DownloadArchive(archive, download, outputPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
DesiredThreads.OnNext(DiskThreads);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SendDownloadMetrics(List<Archive> missing)
|
private async Task SendDownloadMetrics(List<Archive> missing)
|
||||||
|
@ -56,7 +56,8 @@ namespace Wabbajack.Lib
|
|||||||
await Metrics.Send(Metrics.BeginInstall, ModList.Name);
|
await Metrics.Send(Metrics.BeginInstall, ModList.Name);
|
||||||
Utils.Log("Configuring Processor");
|
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;
|
FileExtractor2.FavorPerfOverRAM = FavorPerfOverRam;
|
||||||
|
|
||||||
if (GameFolder == null)
|
if (GameFolder == null)
|
||||||
@ -123,14 +124,23 @@ namespace Wabbajack.Lib
|
|||||||
UpdateTracker.NextStep("Optimizing ModList");
|
UpdateTracker.NextStep("Optimizing ModList");
|
||||||
await OptimizeModlist();
|
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;
|
if (cancel.IsCancellationRequested) return false;
|
||||||
UpdateTracker.NextStep("Hashing Archives");
|
UpdateTracker.NextStep("Hashing Archives");
|
||||||
await HashArchives();
|
await HashArchives();
|
||||||
|
|
||||||
|
// Set to download thread count.
|
||||||
|
DesiredThreads.OnNext(DownloadThreads);
|
||||||
|
|
||||||
if (cancel.IsCancellationRequested) return false;
|
if (cancel.IsCancellationRequested) return false;
|
||||||
UpdateTracker.NextStep("Downloading Missing Archives");
|
UpdateTracker.NextStep("Downloading Missing Archives");
|
||||||
await DownloadArchives();
|
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;
|
if (cancel.IsCancellationRequested) return false;
|
||||||
UpdateTracker.NextStep("Hashing Remaining Archives");
|
UpdateTracker.NextStep("Hashing Remaining Archives");
|
||||||
await HashArchives();
|
await HashArchives();
|
||||||
@ -146,6 +156,9 @@ namespace Wabbajack.Lib
|
|||||||
Error("Cannot continue, was unable to download one or more archives");
|
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;
|
if (cancel.IsCancellationRequested) return false;
|
||||||
UpdateTracker.NextStep("Extracting Modlist contents");
|
UpdateTracker.NextStep("Extracting Modlist contents");
|
||||||
await ExtractModlist();
|
await ExtractModlist();
|
||||||
|
@ -116,9 +116,10 @@ namespace Wabbajack
|
|||||||
{
|
{
|
||||||
public PerformanceSettings()
|
public PerformanceSettings()
|
||||||
{
|
{
|
||||||
|
_reduceHDDThreads = true;
|
||||||
_favorPerfOverRam = false;
|
_favorPerfOverRam = false;
|
||||||
_diskThreads = Environment.ProcessorCount;
|
_diskThreads = Environment.ProcessorCount;
|
||||||
_downloadThreads = Environment.ProcessorCount;
|
_downloadThreads = Environment.ProcessorCount <= 8 ? Environment.ProcessorCount : 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _downloadThreads;
|
private int _downloadThreads;
|
||||||
@ -127,6 +128,9 @@ namespace Wabbajack
|
|||||||
private int _diskThreads;
|
private int _diskThreads;
|
||||||
public int DiskThreads { get => _diskThreads; set => RaiseAndSetIfChanged(ref _diskThreads, value); }
|
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;
|
private bool _favorPerfOverRam;
|
||||||
public bool FavorPerfOverRam { get => _favorPerfOverRam; set => RaiseAndSetIfChanged(ref _favorPerfOverRam, value); }
|
public bool FavorPerfOverRam { get => _favorPerfOverRam; set => RaiseAndSetIfChanged(ref _favorPerfOverRam, value); }
|
||||||
|
|
||||||
@ -135,6 +139,7 @@ namespace Wabbajack
|
|||||||
{
|
{
|
||||||
processor.DownloadThreads = DownloadThreads;
|
processor.DownloadThreads = DownloadThreads;
|
||||||
processor.DiskThreads = DiskThreads;
|
processor.DiskThreads = DiskThreads;
|
||||||
|
processor.ReduceHDDThreads = ReduceHDDThreads;
|
||||||
processor.FavorPerfOverRam = FavorPerfOverRam;
|
processor.FavorPerfOverRam = FavorPerfOverRam;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,18 +76,30 @@ namespace Wabbajack
|
|||||||
})
|
})
|
||||||
.ToProperty(this, nameof(CanInstall));
|
.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)
|
this.WhenAny(x => x.Location.TargetPath)
|
||||||
.Skip(1) // Don't do it initially
|
.Skip(1) // Don't do it initially
|
||||||
.Subscribe(installPath =>
|
.Subscribe(installPath =>
|
||||||
{
|
{
|
||||||
if (DownloadLocation.TargetPath == default)
|
if (DownloadLocation.TargetPath == default || DownloadLocation.TargetPath == installPath)
|
||||||
{
|
{
|
||||||
DownloadLocation.TargetPath = installPath.Combine("downloads");
|
DownloadLocation.TargetPath = installPath.Combine("downloads");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.DisposeWith(CompositeDisposable);
|
.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
|
// Load settings
|
||||||
_CurrentSettings = installerVM.WhenAny(x => x.ModListLocation.TargetPath)
|
_CurrentSettings = installerVM.WhenAny(x => x.ModListLocation.TargetPath)
|
||||||
.Select(path => path == default ? null : installerVM.MWVM.Settings.Installer.Mo2ModlistSettings.TryCreate(path))
|
.Select(path => path == default ? null : installerVM.MWVM.Settings.Installer.Mo2ModlistSettings.TryCreate(path))
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
<RowDefinition Height="25" />
|
<RowDefinition Height="25" />
|
||||||
<RowDefinition Height="25" />
|
<RowDefinition Height="25" />
|
||||||
<RowDefinition Height="25" />
|
<RowDefinition Height="25" />
|
||||||
|
<RowDefinition Height="25" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@ -67,10 +68,20 @@
|
|||||||
Maximum="128"
|
Maximum="128"
|
||||||
Minimum="2" />
|
Minimum="2" />
|
||||||
<TextBlock Grid.Row="5" Grid.Column="0"
|
<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"
|
x:Name="FavorPerfOverRamLabel"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="Favor performance over RAM Usage" />
|
Text="Favor performance over RAM Usage" />
|
||||||
<CheckBox Grid.Row="5" Grid.Column="2"
|
<CheckBox Grid.Row="6" Grid.Column="2"
|
||||||
x:Name="FavorPerfOverRam"
|
x:Name="FavorPerfOverRam"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
@ -39,6 +39,8 @@ namespace Wabbajack
|
|||||||
vmToViewConverter: x => x,
|
vmToViewConverter: x => x,
|
||||||
viewToVmConverter: x => (int)(x ?? 0))
|
viewToVmConverter: x => (int)(x ?? 0))
|
||||||
.DisposeWith(disposable);
|
.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)
|
this.BindStrict(this.ViewModel, x => x.FavorPerfOverRam, x => x.FavorPerfOverRam.IsChecked)
|
||||||
.DisposeWith(disposable);
|
.DisposeWith(disposable);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user