mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
3.0.0.2
This commit is contained in:
parent
390e34c76c
commit
8fd5794936
@ -1,6 +1,12 @@
|
|||||||
### Changelog
|
### Changelog
|
||||||
|
|
||||||
#### Version - 3.0.0.1 - 8/19/2020
|
#### Version - 3.0.0.2 - 8/19/2022
|
||||||
|
* Be more tolerant of bad picture Urls while validating Nexus Downloads (thanks ForgottenGlory)
|
||||||
|
* Fix loading and saving of several compiler fields
|
||||||
|
* Show Author/Image/Title in compiler configuration page
|
||||||
|
* Attempt to fix a "Not run on owning thread" issue during compilation
|
||||||
|
|
||||||
|
#### Version - 3.0.0.1 - 8/19/2022
|
||||||
* Fix the utterly broken build pipeline, app actually runs now
|
* Fix the utterly broken build pipeline, app actually runs now
|
||||||
* Trigger login pages for sites if the user doesn't log in before installing
|
* Trigger login pages for sites if the user doesn't log in before installing
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ using Wabbajack.Common;
|
|||||||
using Wabbajack.Compiler;
|
using Wabbajack.Compiler;
|
||||||
using Wabbajack.DTOs;
|
using Wabbajack.DTOs;
|
||||||
using Wabbajack.DTOs.JsonConverters;
|
using Wabbajack.DTOs.JsonConverters;
|
||||||
|
using Wabbajack.Extensions;
|
||||||
using Wabbajack.Installer;
|
using Wabbajack.Installer;
|
||||||
using Wabbajack.Models;
|
using Wabbajack.Models;
|
||||||
using Wabbajack.Networking.WabbajackClientApi;
|
using Wabbajack.Networking.WabbajackClientApi;
|
||||||
@ -216,6 +217,14 @@ namespace Wabbajack
|
|||||||
|
|
||||||
BaseGame = settings.Game;
|
BaseGame = settings.Game;
|
||||||
ModListName = settings.ModListName;
|
ModListName = settings.ModListName;
|
||||||
|
Version = settings.Version?.ToString() ?? "";
|
||||||
|
Author = settings.ModListAuthor;
|
||||||
|
Description = settings.Description;
|
||||||
|
ModListImagePath.TargetPath = settings.ModListImage;
|
||||||
|
Website = settings.ModListWebsite?.ToString() ?? "";
|
||||||
|
Readme = settings.ModListReadme?.ToString() ?? "";
|
||||||
|
IsNSFW = settings.ModlistIsNSFW;
|
||||||
|
|
||||||
Source = settings.Source;
|
Source = settings.Source;
|
||||||
DownloadLocation.TargetPath = settings.Downloads;
|
DownloadLocation.TargetPath = settings.Downloads;
|
||||||
OutputLocation.TargetPath = settings.OutputFile;
|
OutputLocation.TargetPath = settings.OutputFile;
|
||||||
@ -253,12 +262,13 @@ namespace Wabbajack
|
|||||||
|
|
||||||
var events = Observable.FromEventPattern<StatusUpdate>(h => compiler.OnStatusUpdate += h,
|
var events = Observable.FromEventPattern<StatusUpdate>(h => compiler.OnStatusUpdate += h,
|
||||||
h => compiler.OnStatusUpdate -= h)
|
h => compiler.OnStatusUpdate -= h)
|
||||||
.Throttle(TimeSpan.FromSeconds(0.5))
|
.Debounce(TimeSpan.FromSeconds(0.5))
|
||||||
.ObserveOnGuiThread()
|
.ObserveOnGuiThread()
|
||||||
.Subscribe(update =>
|
.Subscribe(update =>
|
||||||
{
|
{
|
||||||
StatusText = $"{update.EventArgs.StatusText} - {update.EventArgs.StepProgress}";
|
var s = update.EventArgs;
|
||||||
StatusProgress = update.EventArgs.StepsProgress;
|
StatusText = $"[{s.StepsProgress}] {s.StatusText}";
|
||||||
|
StatusProgress = s.StepProgress;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -341,10 +351,20 @@ namespace Wabbajack
|
|||||||
|
|
||||||
private CompilerSettings GetSettings()
|
private CompilerSettings GetSettings()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
System.Version.TryParse(Version, out var pversion);
|
||||||
|
Uri.TryCreate(Website, UriKind.Absolute, out var websiteUri);
|
||||||
|
|
||||||
return new CompilerSettings
|
return new CompilerSettings
|
||||||
{
|
{
|
||||||
ModListName = ModListName,
|
ModListName = ModListName,
|
||||||
ModListAuthor = Author,
|
ModListAuthor = Author,
|
||||||
|
Version = pversion ?? new Version(),
|
||||||
|
Description = Description,
|
||||||
|
ModListReadme = Readme,
|
||||||
|
ModListImage = ModListImagePath.TargetPath,
|
||||||
|
ModlistIsNSFW = IsNSFW,
|
||||||
|
ModListWebsite = websiteUri ?? new Uri("http://www.wabbajack.org"),
|
||||||
Downloads = DownloadLocation.TargetPath,
|
Downloads = DownloadLocation.TargetPath,
|
||||||
Source = Source,
|
Source = Source,
|
||||||
Game = BaseGame,
|
Game = BaseGame,
|
||||||
|
@ -39,6 +39,22 @@ namespace Wabbajack
|
|||||||
.BindToStrict(this, x => x.CompilationComplete.TitleText.Text)
|
.BindToStrict(this, x => x.CompilationComplete.TitleText.Text)
|
||||||
.DisposeWith(disposables);
|
.DisposeWith(disposables);
|
||||||
|
|
||||||
|
ViewModel.WhenAny(vm => vm.ModListImagePath.TargetPath)
|
||||||
|
.Where(i => i.FileExists())
|
||||||
|
.Select(i => (UIUtils.TryGetBitmapImageFromFile(i, out var img), img))
|
||||||
|
.Where(i => i.Item1)
|
||||||
|
.Select(i => i.img)
|
||||||
|
.BindToStrict(this, view => view.DetailImage.Image);
|
||||||
|
|
||||||
|
ViewModel.WhenAny(vm => vm.ModListName)
|
||||||
|
.BindToStrict(this, view => view.DetailImage.Title);
|
||||||
|
|
||||||
|
ViewModel.WhenAny(vm => vm.Author)
|
||||||
|
.BindToStrict(this, view => view.DetailImage.Author);
|
||||||
|
|
||||||
|
ViewModel.WhenAny(vm => vm.Description)
|
||||||
|
.BindToStrict(this, view => view.DetailImage.Description);
|
||||||
|
|
||||||
CompilationComplete.GoToModlistButton.Command = ReactiveCommand.Create(() =>
|
CompilationComplete.GoToModlistButton.Command = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
UIUtils.OpenFolder(ViewModel.OutputLocation.TargetPath.Parent);
|
UIUtils.OpenFolder(ViewModel.OutputLocation.TargetPath.Parent);
|
||||||
|
@ -70,10 +70,12 @@ namespace Wabbajack
|
|||||||
|
|
||||||
// Status
|
// Status
|
||||||
ViewModel.WhenAnyValue(vm => vm.StatusText)
|
ViewModel.WhenAnyValue(vm => vm.StatusText)
|
||||||
|
.ObserveOnGuiThread()
|
||||||
.BindToStrict(this, view => view.TopProgressBar.Title)
|
.BindToStrict(this, view => view.TopProgressBar.Title)
|
||||||
.DisposeWith(disposables);
|
.DisposeWith(disposables);
|
||||||
|
|
||||||
ViewModel.WhenAnyValue(vm => vm.StatusProgress)
|
ViewModel.WhenAnyValue(vm => vm.StatusProgress)
|
||||||
|
.ObserveOnGuiThread()
|
||||||
.Select(p => p.Value)
|
.Select(p => p.Value)
|
||||||
.BindToStrict(this, view => view.TopProgressBar.ProgressPercent)
|
.BindToStrict(this, view => view.TopProgressBar.ProgressPercent)
|
||||||
.DisposeWith(disposables);
|
.DisposeWith(disposables);
|
||||||
|
@ -118,7 +118,7 @@ public abstract class ACompiler
|
|||||||
_logger.LogInformation("Compiler Step: {Step}", statusText);
|
_logger.LogInformation("Compiler Step: {Step}", statusText);
|
||||||
|
|
||||||
if (OnStatusUpdate != null)
|
if (OnStatusUpdate != null)
|
||||||
OnStatusUpdate(this, new StatusUpdate(statusCategory, $"[{_currentStep}/{MaxSteps}] " + statusText,
|
OnStatusUpdate(this, new StatusUpdate(statusCategory, statusText,
|
||||||
Percent.FactoryPutInRange(_currentStep, MaxSteps),
|
Percent.FactoryPutInRange(_currentStep, MaxSteps),
|
||||||
Percent.Zero));
|
Percent.Zero));
|
||||||
}
|
}
|
||||||
@ -138,6 +138,22 @@ public abstract class ACompiler
|
|||||||
Percent.FactoryPutInRange(_currentStepProgress, _maxStepProgress)));
|
Percent.FactoryPutInRange(_currentStepProgress, _maxStepProgress)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateProgressAbsolute(long cur, long max)
|
||||||
|
{
|
||||||
|
_currentStepProgress = cur;
|
||||||
|
_maxStepProgress = max;
|
||||||
|
|
||||||
|
lock (_updateStopWatch)
|
||||||
|
{
|
||||||
|
if (_updateStopWatch.ElapsedMilliseconds < 100) return;
|
||||||
|
_updateStopWatch.Restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OnStatusUpdate != null)
|
||||||
|
OnStatusUpdate(this, new StatusUpdate(_statusCategory, _statusText, Percent.FactoryPutInRange(_currentStep, MaxSteps),
|
||||||
|
Percent.FactoryPutInRange(_currentStepProgress, _maxStepProgress)));
|
||||||
|
}
|
||||||
|
|
||||||
public abstract Task<bool> Begin(CancellationToken token);
|
public abstract Task<bool> Begin(CancellationToken token);
|
||||||
|
|
||||||
internal RelativePath IncludeId()
|
internal RelativePath IncludeId()
|
||||||
@ -266,9 +282,10 @@ public abstract class ACompiler
|
|||||||
|
|
||||||
protected async Task CleanInvalidArchivesAndFillState()
|
protected async Task CleanInvalidArchivesAndFillState()
|
||||||
{
|
{
|
||||||
NextStep("Compiling", "Cleaning Invalid Archives");
|
NextStep("Compiling", "Cleaning Invalid Archives", IndexedArchives.Count);
|
||||||
var remove = await IndexedArchives.PKeepAll(CompilerLimiter, async a =>
|
var remove = await IndexedArchives.PKeepAll(CompilerLimiter, async a =>
|
||||||
{
|
{
|
||||||
|
UpdateProgress(1);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var resolved = await ResolveArchive(a);
|
var resolved = await ResolveArchive(a);
|
||||||
|
@ -25,7 +25,7 @@ public class CompilerSettings
|
|||||||
public string ModListName { get; set; } = "";
|
public string ModListName { get; set; } = "";
|
||||||
public string ModListAuthor { get; set; } = "";
|
public string ModListAuthor { get; set; } = "";
|
||||||
public string ModListDescription { get; set; } = "";
|
public string ModListDescription { get; set; } = "";
|
||||||
public string ModlistReadme { get; set; } = "";
|
public string ModListReadme { get; set; } = "";
|
||||||
public Uri? ModListWebsite { get; set; }
|
public Uri? ModListWebsite { get; set; }
|
||||||
public Version ModlistVersion { get; set; } = Version.Parse("0.0.1.0");
|
public Version ModlistVersion { get; set; } = Version.Parse("0.0.1.0");
|
||||||
public bool PublishUpdate { get; set; } = false;
|
public bool PublishUpdate { get; set; } = false;
|
||||||
@ -62,5 +62,6 @@ public class CompilerSettings
|
|||||||
public RelativePath[] Include { get; set; } = Array.Empty<RelativePath>();
|
public RelativePath[] Include { get; set; } = Array.Empty<RelativePath>();
|
||||||
|
|
||||||
public RelativePath[] AlwaysEnabled { get; set; } = Array.Empty<RelativePath>();
|
public RelativePath[] AlwaysEnabled { get; set; } = Array.Empty<RelativePath>();
|
||||||
|
public Version Version { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
}
|
}
|
@ -79,7 +79,7 @@ public class MO2Compiler : ACompiler
|
|||||||
roots.AddRange(Settings.OtherGames.Append(Settings.Game).Select(g => _locator.GameLocation(g)));
|
roots.AddRange(Settings.OtherGames.Append(Settings.Game).Select(g => _locator.GameLocation(g)));
|
||||||
|
|
||||||
NextStep("Initializing", "Add Roots");
|
NextStep("Initializing", "Add Roots");
|
||||||
await _vfs.AddRoots(roots, token); // Step 1
|
await _vfs.AddRoots(roots, token, async (cur, max) => UpdateProgressAbsolute(cur, max)); // Step 1
|
||||||
|
|
||||||
//await InferMetas(token); // Step 2
|
//await InferMetas(token); // Step 2
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ public class MO2Compiler : ACompiler
|
|||||||
Name = Settings.ModListName,
|
Name = Settings.ModListName,
|
||||||
Author = Settings.ModListAuthor,
|
Author = Settings.ModListAuthor,
|
||||||
Description = Settings.ModListDescription,
|
Description = Settings.ModListDescription,
|
||||||
Readme = Settings.ModlistReadme,
|
Readme = Settings.ModListReadme,
|
||||||
Image = ModListImage != default ? ModListImage.FileName : default,
|
Image = ModListImage != default ? ModListImage.FileName : default,
|
||||||
Website = Settings.ModListWebsite,
|
Website = Settings.ModListWebsite,
|
||||||
Version = Settings.ModlistVersion,
|
Version = Settings.ModlistVersion,
|
||||||
|
@ -185,7 +185,8 @@ public class NexusDownloader : ADownloader<Nexus>, IUrlDownloader
|
|||||||
state.Description = FixupSummary(modInfo.Summary);
|
state.Description = FixupSummary(modInfo.Summary);
|
||||||
state.Version = modInfo.Version;
|
state.Version = modInfo.Version;
|
||||||
state.Author = modInfo.Author;
|
state.Author = modInfo.Author;
|
||||||
state.ImageURL = new Uri(modInfo.PictureUrl);
|
if (Uri.TryCreate(modInfo.PictureUrl, UriKind.Absolute, out var uri))
|
||||||
|
state.ImageURL = uri;
|
||||||
state.Name = modInfo.Name;
|
state.Name = modInfo.Name;
|
||||||
state.IsNSFW = modInfo.ContainsAdultContent;
|
state.IsNSFW = modInfo.ContainsAdultContent;
|
||||||
|
|
||||||
|
@ -49,4 +49,9 @@ public class CesiVFSCache : IVfsCache
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task Clean()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,4 +9,5 @@ public interface IVfsCache
|
|||||||
{
|
{
|
||||||
public Task<IndexedVirtualFile?> Get(Hash hash, IStreamFactory sf, CancellationToken token);
|
public Task<IndexedVirtualFile?> Get(Hash hash, IStreamFactory sf, CancellationToken token);
|
||||||
public Task Put(IndexedVirtualFile file, CancellationToken token);
|
public Task Put(IndexedVirtualFile file, CancellationToken token);
|
||||||
|
Task Clean();
|
||||||
}
|
}
|
@ -91,7 +91,7 @@ public class Context
|
|||||||
return newIndex;
|
return newIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IndexRoot> AddRoots(List<AbsolutePath> roots, CancellationToken token)
|
public async Task<IndexRoot> AddRoots(List<AbsolutePath> roots, CancellationToken token, Func<long, long, Task>? updateFunction = null)
|
||||||
{
|
{
|
||||||
var native = Index.AllFiles.Where(file => file.IsNative).ToDictionary(file => file.FullPath.Base);
|
var native = Index.AllFiles.Where(file => file.IsNative).ToDictionary(file => file.FullPath.Base);
|
||||||
|
|
||||||
@ -99,12 +99,16 @@ public class Context
|
|||||||
|
|
||||||
var filesToIndex = roots.SelectMany(root => root.EnumerateFiles()).ToList();
|
var filesToIndex = roots.SelectMany(root => root.EnumerateFiles()).ToList();
|
||||||
|
|
||||||
|
var idx = 0;
|
||||||
var allFiles = await filesToIndex
|
var allFiles = await filesToIndex
|
||||||
.PMapAll(async f =>
|
.PMapAll(async f =>
|
||||||
{
|
{
|
||||||
|
using var job = await Limiter.Begin($"Indexing {f.FileName}", 0, token);
|
||||||
if (native.TryGetValue(f, out var found))
|
if (native.TryGetValue(f, out var found))
|
||||||
if (found.LastModified == f.LastModifiedUtc().AsUnixTime() && found.Size == f.Size())
|
if (found.LastModified == f.LastModifiedUtc().AsUnixTime() && found.Size == f.Size())
|
||||||
return found;
|
return found;
|
||||||
|
Interlocked.Increment(ref idx);
|
||||||
|
updateFunction?.Invoke(idx, filesToIndex.Count);
|
||||||
|
|
||||||
return await VirtualFile.Analyze(this, null, new NativeFileStreamFactory(f), f, token);
|
return await VirtualFile.Analyze(this, null, new NativeFileStreamFactory(f), f, token);
|
||||||
}).ToList();
|
}).ToList();
|
||||||
@ -116,6 +120,8 @@ public class Context
|
|||||||
Index = newIndex;
|
Index = newIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VfsCache.Clean();
|
||||||
|
|
||||||
return newIndex;
|
return newIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,4 +45,12 @@ public class FallthroughVFSCache : IVfsCache
|
|||||||
await cache.Put(file, token);
|
await cache.Put(file, token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task Clean()
|
||||||
|
{
|
||||||
|
foreach (var cache in _caches)
|
||||||
|
{
|
||||||
|
await cache.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -71,6 +71,15 @@ public class VFSDiskCache : IVfsCache
|
|||||||
await InsertIntoVFSCache(ivf.Hash, ms);
|
await InsertIntoVFSCache(ivf.Hash, ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task Clean()
|
||||||
|
{
|
||||||
|
await using var cmd = new SQLiteCommand(_conn);
|
||||||
|
cmd.CommandText = @"VACUUM";
|
||||||
|
await cmd.PrepareAsync();
|
||||||
|
|
||||||
|
await cmd.ExecuteNonQueryAsync();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task InsertIntoVFSCache(Hash hash, MemoryStream data)
|
private async Task InsertIntoVFSCache(Hash hash, MemoryStream data)
|
||||||
{
|
{
|
||||||
await using var cmd = new SQLiteCommand(_conn);
|
await using var cmd = new SQLiteCommand(_conn);
|
||||||
|
Loading…
Reference in New Issue
Block a user