mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
MO2Compiler nullability enabled
This commit is contained in:
parent
a29eb93caf
commit
4e1a32caac
@ -21,6 +21,9 @@ namespace Wabbajack
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given values to the dictionary. If a key already exists, it will throw an exception
|
||||
/// </summary>
|
||||
public static void Add<K, V>(this IDictionary<K, V> dict, IEnumerable<KeyValuePair<K, V>> vals)
|
||||
where K : notnull
|
||||
{
|
||||
@ -30,6 +33,9 @@ namespace Wabbajack
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given values to the dictionary. If a key already exists, it will be replaced
|
||||
/// </summary>
|
||||
public static void Set<K, V>(this IDictionary<K, V> dict, IEnumerable<KeyValuePair<K, V>> vals)
|
||||
where K : notnull
|
||||
{
|
||||
@ -38,5 +44,15 @@ namespace Wabbajack
|
||||
dict[val.Key] = val.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the dictionary and adds the given values
|
||||
/// </summary>
|
||||
public static void SetTo<K, V>(this IDictionary<K, V> dict, IEnumerable<KeyValuePair<K, V>> vals)
|
||||
where K : notnull
|
||||
{
|
||||
dict.Clear();
|
||||
dict.Set(vals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,5 +33,32 @@ namespace Wabbajack
|
||||
yield return next;
|
||||
foreach (var itm in coll) yield return itm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts and filters a nullable enumerable to a non-nullable enumerable
|
||||
/// </summary>
|
||||
public static IEnumerable<T> NotNull<T>(this IEnumerable<T?> e)
|
||||
where T : class
|
||||
{
|
||||
// Filter out nulls
|
||||
return e.Where(e => e != null)
|
||||
// Cast to non nullable type
|
||||
.Select(e => e!);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects items that are castable to the desired type
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the original enumerable to cast from</typeparam>
|
||||
/// <typeparam name="R">Type to attempt casting to</typeparam>
|
||||
/// <param name="e">Enumerable to process</param>
|
||||
/// <returns>Enumerable with only objects that were castable</returns>
|
||||
public static IEnumerable<R> WhereCastable<T, R>(this IEnumerable<T> e)
|
||||
where T : class
|
||||
where R : T
|
||||
{
|
||||
return e.Where(e => e is R)
|
||||
.Select(e => (R)e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
Wabbajack.Common/Extensions/ListExt.cs
Normal file
15
Wabbajack.Common/Extensions/ListExt.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Wabbajack.Common
|
||||
{
|
||||
public static class ListExt
|
||||
{
|
||||
public static void SetTo<T>(this List<T> list, IEnumerable<T> rhs)
|
||||
{
|
||||
list.Clear();
|
||||
list.AddRange(rhs);
|
||||
}
|
||||
}
|
||||
}
|
@ -43,9 +43,9 @@ namespace Wabbajack.Lib
|
||||
|
||||
public bool IgnoreMissingFiles { get; set; }
|
||||
|
||||
public ICollection<Archive> SelectedArchives = new List<Archive>();
|
||||
public List<Directive> InstallDirectives = new List<Directive>();
|
||||
public List<RawSourceFile> AllFiles = new List<RawSourceFile>();
|
||||
public readonly List<Archive> SelectedArchives = new List<Archive>();
|
||||
public readonly List<Directive> InstallDirectives = new List<Directive>();
|
||||
public readonly List<RawSourceFile> AllFiles = new List<RawSourceFile>();
|
||||
public ModList ModList = new ModList();
|
||||
|
||||
public List<IndexedArchive> IndexedArchives = new List<IndexedArchive>();
|
||||
@ -222,7 +222,7 @@ namespace Wabbajack.Lib
|
||||
.GroupBy(f => f.File.Hash)
|
||||
.ToDictionary(f => f.Key, f => f.First());
|
||||
|
||||
SelectedArchives = await hashes.PMap(Queue, hash => ResolveArchive(hash, archives));
|
||||
SelectedArchives.SetTo(await hashes.PMap(Queue, hash => ResolveArchive(hash, archives)));
|
||||
}
|
||||
|
||||
public async Task<Archive> ResolveArchive(Hash hash, IDictionary<Hash, IndexedArchive> archives)
|
||||
|
@ -20,12 +20,12 @@ using File = Alphaleonis.Win32.Filesystem.File;
|
||||
using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo;
|
||||
using Game = Wabbajack.Common.Game;
|
||||
using Path = Alphaleonis.Win32.Filesystem.Path;
|
||||
#nullable enable
|
||||
|
||||
namespace Wabbajack.Lib
|
||||
{
|
||||
public class MO2Compiler : ACompiler
|
||||
{
|
||||
|
||||
private AbsolutePath _mo2DownloadsFolder;
|
||||
|
||||
public AbsolutePath MO2Folder;
|
||||
@ -38,7 +38,7 @@ namespace Wabbajack.Lib
|
||||
|
||||
public override AbsolutePath GamePath { get; }
|
||||
|
||||
public GameMetaData CompilingGame { get; set; }
|
||||
public GameMetaData CompilingGame { get; }
|
||||
|
||||
public override AbsolutePath ModListOutputFolder => ((RelativePath)"output_folder").RelativeToEntryPoint();
|
||||
|
||||
@ -48,6 +48,17 @@ namespace Wabbajack.Lib
|
||||
Consts.LocalAppDataPath.Combine(
|
||||
$"vfs_compile_cache-{Path.Combine((string)MO2Folder ?? "Unknown", "ModOrganizer.exe").StringSha256Hex()}.bin");
|
||||
|
||||
public dynamic MO2Ini { get; }
|
||||
|
||||
public static AbsolutePath GetTypicalDownloadsFolder(AbsolutePath mo2Folder) => mo2Folder.Combine("downloads");
|
||||
|
||||
public AbsolutePath MO2ProfileDir => MO2Folder.Combine("profiles", MO2Profile);
|
||||
|
||||
public ConcurrentBag<Directive> ExtraFiles { get; } = new ConcurrentBag<Directive>();
|
||||
public Dictionary<AbsolutePath, dynamic> ModInis { get; } = new Dictionary<AbsolutePath, dynamic>();
|
||||
|
||||
public HashSet<string> SelectedProfiles { get; set; } = new HashSet<string>();
|
||||
|
||||
public MO2Compiler(AbsolutePath mo2Folder, string mo2Profile, AbsolutePath outputFile)
|
||||
: base(steps: 20)
|
||||
{
|
||||
@ -60,8 +71,6 @@ namespace Wabbajack.Lib
|
||||
ModListOutputFile = outputFile;
|
||||
}
|
||||
|
||||
public dynamic MO2Ini { get; }
|
||||
|
||||
public AbsolutePath MO2DownloadsFolder
|
||||
{
|
||||
get
|
||||
@ -76,16 +85,6 @@ namespace Wabbajack.Lib
|
||||
set => _mo2DownloadsFolder = value;
|
||||
}
|
||||
|
||||
public static AbsolutePath GetTypicalDownloadsFolder(AbsolutePath mo2Folder) => mo2Folder.Combine("downloads");
|
||||
|
||||
public AbsolutePath MO2ProfileDir => MO2Folder.Combine("profiles", MO2Profile);
|
||||
|
||||
internal UserStatus User { get; private set; }
|
||||
public ConcurrentBag<Directive> ExtraFiles { get; private set; }
|
||||
public Dictionary<AbsolutePath, dynamic> ModInis { get; private set; }
|
||||
|
||||
public HashSet<string> SelectedProfiles { get; set; } = new HashSet<string>();
|
||||
|
||||
protected override async Task<bool> _Begin(CancellationToken cancel)
|
||||
{
|
||||
if (cancel.IsCancellationRequested) return false;
|
||||
@ -127,6 +126,11 @@ namespace Wabbajack.Lib
|
||||
|
||||
if (lootPath.Exists)
|
||||
{
|
||||
if (CompilingGame.MO2Name == null)
|
||||
{
|
||||
throw new ArgumentException("Compiling game had no MO2 name specified.");
|
||||
}
|
||||
|
||||
var lootGameDirs = new []
|
||||
{
|
||||
CompilingGame.MO2Name, // most of the games use the MO2 name
|
||||
@ -217,10 +221,9 @@ namespace Wabbajack.Lib
|
||||
.GroupBy(f => f.Hash)
|
||||
.ToDictionary(f => f.Key, f => f.AsEnumerable());
|
||||
|
||||
AllFiles = mo2Files.Concat(gameFiles)
|
||||
AllFiles.SetTo(mo2Files.Concat(gameFiles)
|
||||
.Concat(lootFiles)
|
||||
.DistinctBy(f => f.Path)
|
||||
.ToList();
|
||||
.DistinctBy(f => f.Path));
|
||||
|
||||
Info($"Found {AllFiles.Count} files to build into mod list");
|
||||
|
||||
@ -240,13 +243,10 @@ namespace Wabbajack.Lib
|
||||
Error($"Found {dups.Count} duplicates, exiting");
|
||||
}
|
||||
|
||||
ExtraFiles = new ConcurrentBag<Directive>();
|
||||
|
||||
|
||||
if (cancel.IsCancellationRequested) return false;
|
||||
UpdateTracker.NextStep("Loading INIs");
|
||||
|
||||
ModInis = MO2Folder.Combine(Consts.MO2ModFolderName)
|
||||
ModInis.SetTo(MO2Folder.Combine(Consts.MO2ModFolderName)
|
||||
.EnumerateDirectories()
|
||||
.Select(f =>
|
||||
{
|
||||
@ -255,7 +255,7 @@ namespace Wabbajack.Lib
|
||||
return metaPath.Exists ? (mod_name: f, metaPath.LoadIniFile()) : default;
|
||||
})
|
||||
.Where(f => f.Item1 != default)
|
||||
.ToDictionary(f => f.Item1, f => f.Item2);
|
||||
.Select(f => new KeyValuePair<AbsolutePath, dynamic>(f.Item1, f.Item2)));
|
||||
|
||||
if (cancel.IsCancellationRequested) return false;
|
||||
var stack = MakeStack();
|
||||
@ -271,7 +271,7 @@ namespace Wabbajack.Lib
|
||||
PrintNoMatches(noMatch);
|
||||
if (CheckForNoMatchExit(noMatch)) return false;
|
||||
|
||||
InstallDirectives = results.Where(i => !(i is IgnoredDirectly)).ToList();
|
||||
InstallDirectives.SetTo(results.Where(i => !(i is IgnoredDirectly)));
|
||||
|
||||
Info("Getting Nexus api_key, please click authorize if a browser window appears");
|
||||
|
||||
@ -338,7 +338,7 @@ namespace Wabbajack.Lib
|
||||
{
|
||||
return a;
|
||||
}
|
||||
})).Where(a => a != null).ToHashSet();
|
||||
})).NotNull().ToHashSet();
|
||||
|
||||
if (remove.Count == 0)
|
||||
return;
|
||||
@ -390,7 +390,6 @@ namespace Wabbajack.Lib
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private async Task IncludeArchiveMetadata()
|
||||
{
|
||||
Utils.Log($"Including {SelectedArchives.Count} .meta files for downloads");
|
||||
@ -412,13 +411,12 @@ namespace Wabbajack.Lib
|
||||
/// </summary>
|
||||
private void ResetMembers()
|
||||
{
|
||||
AllFiles = null;
|
||||
InstallDirectives = null;
|
||||
SelectedArchives = null;
|
||||
ExtraFiles = null;
|
||||
AllFiles.Clear();
|
||||
InstallDirectives.Clear();
|
||||
SelectedArchives.Clear();
|
||||
ExtraFiles.Clear();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Fills in the Patch fields in files that require them
|
||||
/// </summary>
|
||||
@ -488,8 +486,7 @@ namespace Wabbajack.Lib
|
||||
return returnStream;
|
||||
}
|
||||
|
||||
Error($"Couldn't load data for {to}");
|
||||
return null;
|
||||
throw new ArgumentException($"Couldn't load data for {to}");
|
||||
}
|
||||
|
||||
public override IEnumerable<ICompilationStep> GetStack()
|
||||
@ -568,12 +565,5 @@ namespace Wabbajack.Lib
|
||||
new DropAll(this)
|
||||
};
|
||||
}
|
||||
|
||||
public class IndexedFileMatch
|
||||
{
|
||||
public IndexedArchive Archive;
|
||||
public IndexedArchiveEntry Entry;
|
||||
public DateTime LastModified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user