Merge pull request #1378 from wabbajack-tools/install-registry

Create a global registry of the location of all installed modlists
This commit is contained in:
Timothy Baldridge 2021-03-19 16:30:43 -07:00 committed by GitHub
commit 4ea7d92385
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 98 additions and 2 deletions

View File

@ -138,6 +138,8 @@ namespace Wabbajack.Common
public static RelativePath SettingsIni = (RelativePath)"settings.ini";
public static byte SettingsVersion => 2;
public static TimeSpan MaxVerifyTime => TimeSpan.FromMinutes(10);
public static Extension ModlistMetadataExtension = new(".modlist_metadata");
public static readonly string WabbajackAuthoredFilesPrefix = "https://wabbajack.b-cdn.net/";
public static RelativePath NativeSettingsJson = (RelativePath)"native_compiler_settings.json";

View File

@ -62,7 +62,7 @@ namespace Wabbajack.Common
public static void ToJson<T>(this T obj, Stream stream, bool useGenericSettings = false, bool prettyPrint = false)
{
using var tw = new StreamWriter(stream, Encoding.UTF8, bufferSize: 1024, leaveOpen: true);
using var tw = new StreamWriter(stream, new UTF8Encoding(false), bufferSize: 1024, leaveOpen: true);
using var writer = new JsonTextWriter(tw);
JsonSerializerSettings settings = (useGenericSettings, prettyPrint) switch
@ -93,6 +93,12 @@ namespace Wabbajack.Common
return JsonConvert.DeserializeObject<T>(filename.ReadAllText(), JsonSettings)!;
}
public static async Task<T> FromJsonAsync<T>(this AbsolutePath filename)
{
return JsonConvert.DeserializeObject<T>(await filename.ReadAllTextAsync(), JsonSettings)!;
}
public static T FromJsonString<T>(this string data)
{
return JsonConvert.DeserializeObject<T>(data, JsonSettings)!;

View File

@ -22,6 +22,7 @@ using File = Alphaleonis.Win32.Filesystem.File;
using Path = Alphaleonis.Win32.Filesystem.Path;
using SectionData = Wabbajack.Common.SectionData;
using System.Collections.Generic;
using Wabbajack.Lib.ModListRegistry;
using Wabbajack.VirtualFileSystem;
namespace Wabbajack.Lib
@ -33,6 +34,8 @@ namespace Wabbajack.Lib
public override ModManager ModManager => ModManager.MO2;
public AbsolutePath? GameFolder { get; set; }
public ModlistMetadata? Metadata { get; set; }
public MO2Installer(AbsolutePath archive, ModList modList, AbsolutePath outputFolder, AbsolutePath downloadFolder, SystemParameters parameters)
: base(
@ -194,8 +197,9 @@ namespace Wabbajack.Lib
UpdateTracker.NextStep("Create Empty Output Mods");
CreateOutputMods();
UpdateTracker.NextStep("Updating System-specific ini settings");
UpdateTracker.NextStep("Updating System-specific ini settings and writing metadata");
SetScreenSizeInPrefs();
await InstalledModLists.AddModListInstall(Metadata, ModList, OutputFolder, DownloadFolder, ModListArchive);
UpdateTracker.NextStep("Compacting files");
await CompactFiles();

View File

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Wabbajack.Common;
using Wabbajack.Common.Serialization.Json;
namespace Wabbajack.Lib.ModListRegistry
{
public class InstalledModLists
{
public static AbsolutePath InstalledModlistsLocation = Consts.LocalAppDataPath.Combine("installed_modlists.json");
private static AsyncLock _lock = new();
public static async Task AddModListInstall(ModlistMetadata? metadata, ModList modList, AbsolutePath installPath,
AbsolutePath downloadPath, AbsolutePath wabbjackPath)
{
modList = modList.Clone();
modList.Directives = new List<Directive>();
modList.Archives = new List<Archive>();
var newRecord = new ModListInstall()
{
Metadata = metadata,
ModList = modList,
InstallationPath = installPath,
DownloadPath = downloadPath,
WabbajackPath = wabbjackPath,
};
await UpsertInstall(newRecord);
}
public static async Task UpsertInstall(ModListInstall newRecord)
{
using var _ = await _lock.WaitAsync();
Dictionary<AbsolutePath, ModListInstall> oldRecords = new();
if (InstalledModlistsLocation.Exists)
oldRecords = await InstalledModlistsLocation.FromJsonAsync<Dictionary<AbsolutePath, ModListInstall>>();
oldRecords[newRecord.InstallationPath] = newRecord;
CleanEntries(oldRecords);
await oldRecords.ToJsonAsync(InstalledModlistsLocation);
}
private static void CleanEntries(Dictionary<AbsolutePath, ModListInstall> oldRecords)
{
oldRecords.Keys
.Where(k => !k.IsDirectory)
.ToArray()
.Do(k => oldRecords.Remove(k));
}
}
[JsonName("ModListInstall")]
public class ModListInstall
{
public ModlistMetadata? Metadata { get; set; }
public ModList ModList { get; set; } = new();
public AbsolutePath InstallationPath { get; set; }
public AbsolutePath DownloadPath { get; set; }
public AbsolutePath WabbajackPath { get; set; }
public DateTime InstalledAt { get; set; } = DateTime.UtcNow;
}
}

View File

@ -199,6 +199,9 @@ namespace Wabbajack
// Want to rehash to current file, even if failed?
await Location.FileHashCachedAsync();
Utils.Log($"Done hashing {Metadata.Links.MachineURL}");
await Metadata.ToJsonAsync(Location.WithExtension(Consts.ModlistMetadataExtension));
tcs.SetResult(result);
}
catch (Exception ex)

View File

@ -168,6 +168,7 @@ namespace Wabbajack
downloadFolder: DownloadLocation.TargetPath,
parameters: SystemParametersConstructor.Create()))
{
installer.Metadata = Parent.ModList.SourceModListMetadata;
installer.UseCompression = Parent.MWVM.Settings.Filters.UseCompression;
Parent.MWVM.Settings.Performance.SetProcessorSettings(installer);

View File

@ -7,12 +7,14 @@ using System.Reactive.Linq;
using System.Windows.Media.Imaging;
using Wabbajack.Common;
using Wabbajack.Lib;
using Wabbajack.Lib.ModListRegistry;
namespace Wabbajack
{
public class ModListVM : ViewModel
{
public ModList SourceModList { get; private set; }
public ModlistMetadata SourceModListMetadata { get; private set; }
public Exception Error { get; }
public AbsolutePath ModListPath { get; }
public string Name => SourceModList?.Name;
@ -36,6 +38,18 @@ namespace Wabbajack
try
{
SourceModList = AInstaller.LoadFromFile(modListPath);
var metadataPath = modListPath.WithExtension(Consts.ModlistMetadataExtension);
if (metadataPath.Exists)
{
try
{
SourceModListMetadata = metadataPath.FromJson<ModlistMetadata>();
}
catch (Exception)
{
SourceModListMetadata = null;
}
}
}
catch (Exception ex)
{