Don't delete profile specific saves, don't include profile specific saves

This commit is contained in:
Timothy Baldridge 2020-06-30 21:46:26 -06:00
parent d48489d4fe
commit 69238e5c0c
35 changed files with 75 additions and 479 deletions

View File

@ -114,10 +114,11 @@ namespace Wabbajack.Common
public bool IsFile => File.Exists(_path); public bool IsFile => File.Exists(_path);
public bool IsDirectory => Directory.Exists(_path); public bool IsDirectory => Directory.Exists(_path);
public async Task DeleteDirectory() public async Task DeleteDirectory(bool dontDeleteIfNotEmpty = false)
{ {
if (IsDirectory) if (IsDirectory)
{ {
if (dontDeleteIfNotEmpty && (EnumerateFiles().Any() || EnumerateDirectories().Any())) return;
await Utils.DeleteDirectory(this); await Utils.DeleteDirectory(this);
} }
} }

View File

@ -356,6 +356,10 @@ namespace Wabbajack.Lib
var indexed = ModList.Directives.ToDictionary(d => d.To); var indexed = ModList.Directives.ToDictionary(d => d.To);
var profileFolder = OutputFolder.Combine("profiles");
var savePath = (RelativePath)"saves";
UpdateTracker.NextStep("Looking for files to delete"); UpdateTracker.NextStep("Looking for files to delete");
await OutputFolder.EnumerateFiles() await OutputFolder.EnumerateFiles()
.PMap(Queue, UpdateTracker, async f => .PMap(Queue, UpdateTracker, async f =>
@ -365,6 +369,8 @@ namespace Wabbajack.Lib
if (indexed.ContainsKey(relativeTo) || f.InFolder(DownloadFolder)) if (indexed.ContainsKey(relativeTo) || f.InFolder(DownloadFolder))
return; return;
if (f.InFolder(profileFolder) && f.Parent.FileName == savePath) return;
Utils.Log($"Deleting {relativeTo} it's not part of this ModList"); Utils.Log($"Deleting {relativeTo} it's not part of this ModList");
await f.DeleteAsync(); await f.DeleteAsync();
}); });
@ -394,7 +400,7 @@ namespace Wabbajack.Lib
.ToList(); .ToList();
foreach (var dir in toDelete) foreach (var dir in toDelete)
{ {
await dir.DeleteDirectory(); await dir.DeleteDirectory(dontDeleteIfNotEmpty:true);
} }
} }
catch (Exception) catch (Exception)

View File

@ -12,6 +12,5 @@ namespace Wabbajack.Lib.CompilationSteps
} }
public abstract ValueTask<Directive?> Run(RawSourceFile source); public abstract ValueTask<Directive?> Run(RawSourceFile source);
public abstract IState GetState();
} }
} }

View File

@ -46,11 +46,6 @@ namespace Wabbajack.Lib.CompilationSteps
}; };
} }
public override IState GetState()
{
return new State();
}
public override async ValueTask<Directive?> Run(RawSourceFile source) public override async ValueTask<Directive?> Run(RawSourceFile source)
{ {
if (!Consts.SupportedBSAs.Contains(source.Path.Extension)) return null; if (!Consts.SupportedBSAs.Contains(source.Path.Extension)) return null;
@ -108,14 +103,5 @@ namespace Wabbajack.Lib.CompilationSteps
await _cleanup(); await _cleanup();
return directive; return directive;
} }
[JsonObject("DeconstructBSAs")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new DeconstructBSAs(compiler);
}
}
} }
} }

View File

@ -40,19 +40,5 @@ namespace Wabbajack.Lib.CompilationSteps
return result; return result;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("DirectMatch")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new DirectMatch(compiler);
}
}
} }
} }

View File

@ -16,19 +16,5 @@ namespace Wabbajack.Lib.CompilationSteps
result.Reason = "No Match in Stack"; result.Reason = "No Match in Stack";
return result; return result;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("DropAll")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new DropAll(compiler);
}
}
} }
} }

View File

@ -5,11 +5,5 @@ namespace Wabbajack.Lib.CompilationSteps
public interface ICompilationStep public interface ICompilationStep
{ {
ValueTask<Directive?> Run(RawSourceFile source); ValueTask<Directive?> Run(RawSourceFile source);
IState GetState();
}
public interface IState
{
ICompilationStep CreateStep(ACompiler compiler);
} }
} }

View File

@ -35,11 +35,6 @@ namespace Wabbajack.Lib.CompilationSteps
return r; return r;
} }
public override IState GetState()
{
return new State();
}
public static bool IsAlwaysEnabled(dynamic data) public static bool IsAlwaysEnabled(dynamic data)
{ {
if (data == null) if (data == null)
@ -53,14 +48,5 @@ namespace Wabbajack.Lib.CompilationSteps
return true; return true;
return false; return false;
} }
[JsonObject("IgnoreDisabledMods")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IgnoreDisabledMods(compiler);
}
}
} }
} }

View File

@ -21,26 +21,5 @@ namespace Wabbajack.Lib.CompilationSteps
result.Reason = _reason; result.Reason = _reason;
return result; return result;
} }
public override IState GetState()
{
return new State(_postfix);
}
[JsonObject("IgnoreEndsWith")]
public class State : IState
{
public string Postfix { get; set; }
public State(string postfix)
{
Postfix = postfix;
}
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IgnoreEndsWith(compiler, Postfix);
}
}
} }
} }

View File

@ -20,19 +20,5 @@ namespace Wabbajack.Lib.CompilationSteps
i.Reason = "Default game file"; i.Reason = "Default game file";
return i; return i;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IgnoreGameFiles")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IgnoreGameFiles(compiler);
}
}
} }
} }

View File

@ -26,18 +26,5 @@ namespace Wabbajack.Lib.CompilationSteps
return result; return result;
} }
public override IState GetState()
{
return new State();
}
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IgnoreGameFilesIfGameFolderFilesExist(compiler);
}
}
} }
} }

View File

@ -21,26 +21,5 @@ namespace Wabbajack.Lib.CompilationSteps
result.Reason = _reason; result.Reason = _reason;
return result; return result;
} }
public override IState GetState()
{
return new State(_pattern);
}
[JsonObject("IgnorePathContains")]
public class State : IState
{
public string Pattern { get; set; }
public State(string pattern)
{
Pattern = pattern;
}
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IgnorePathContains(compiler, Pattern);
}
}
} }
} }

View File

@ -24,26 +24,5 @@ namespace Wabbajack.Lib.CompilationSteps
result.Reason = _reason; result.Reason = _reason;
return result; return result;
} }
public override IState GetState()
{
return new State(_pattern);
}
[JsonObject("IgnorePattern")]
public class State : IState
{
public string Pattern { get; set; }
public State(string pattern)
{
Pattern = pattern;
}
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IgnoreRegex(compiler, Pattern);
}
}
} }
} }

View File

@ -0,0 +1,27 @@
using System.Linq;
using System.Threading.Tasks;
using Wabbajack.Common;
namespace Wabbajack.Lib.CompilationSteps
{
public class IgnoreSaveFiles : MO2CompilationStep
{
private AbsolutePath[] _profilePaths;
public IgnoreSaveFiles(ACompiler compiler) : base(compiler)
{
_profilePaths =
MO2Compiler.SelectedProfiles.Select(p => MO2Compiler.MO2Folder.Combine("profiles", p, "saves")).ToArray();
}
public override async ValueTask<Directive?> Run(RawSourceFile source)
{
if (!_profilePaths.Any(p => source.File.AbsoluteName.InFolder(p)))
return null;
var result = source.EvolveTo<IgnoredDirectly>();
result.Reason = "Ignore Save files";
return result;
}
}
}

View File

@ -26,26 +26,5 @@ namespace Wabbajack.Lib.CompilationSteps
return result; return result;
} }
public override IState GetState()
{
return new State(_prefix);
}
[JsonObject("IgnoreStartsWith")]
public class State : IState
{
public string Prefix { get; set; }
public State(string prefix)
{
Prefix = prefix;
}
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IgnoreStartsWith(compiler, Prefix);
}
}
} }
} }

View File

@ -25,19 +25,5 @@ namespace Wabbajack.Lib.CompilationSteps
result.Reason = "Wabbajack Cruft file"; result.Reason = "Wabbajack Cruft file";
return result; return result;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IgnoreWabbajackInstallCruft")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IgnoreWabbajackInstallCruft(compiler);
}
}
} }
} }

View File

@ -18,19 +18,5 @@ namespace Wabbajack.Lib.CompilationSteps
inline.SourceDataID = await _compiler.IncludeFile(await file.ReadAllAsync()); inline.SourceDataID = await _compiler.IncludeFile(await file.ReadAllAsync());
return inline; return inline;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IncludeAll")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeAll(compiler);
}
}
} }
} }

View File

@ -18,19 +18,5 @@ namespace Wabbajack.Lib.CompilationSteps
result.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync()); result.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync());
return result; return result;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IncludeAllConfigs")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeAllConfigs(compiler);
}
}
} }
} }

View File

@ -25,20 +25,5 @@ namespace Wabbajack.Lib.CompilationSteps
inline.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync()); inline.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync());
return inline; return inline;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IncludeDummyESPs")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeDummyESPs(compiler);
}
}
} }
} }

View File

@ -42,19 +42,5 @@ namespace Wabbajack.Lib.CompilationSteps
res.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync()); res.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync());
return res; return res;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IncludeGenericGamePlugin")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeGenericGamePlugin(compiler);
}
}
} }
} }

View File

@ -21,19 +21,5 @@ namespace Wabbajack.Lib.CompilationSteps
result.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync()); result.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync());
return result; return result;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IncludeLootFiles")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeLootFiles(compiler);
}
}
} }
} }

View File

@ -18,19 +18,5 @@ namespace Wabbajack.Lib.CompilationSteps
e.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync()); e.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync());
return e; return e;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IncludeModIniData")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeModIniData(compiler);
}
}
} }
} }

View File

@ -31,19 +31,5 @@ namespace Wabbajack.Lib.CompilationSteps
c.Reason = "File not for selected profiles"; c.Reason = "File not for selected profiles";
return c; return c;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IgnoreOtherProfiles")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IgnoreOtherProfiles(compiler);
}
}
} }
} }

View File

@ -109,19 +109,5 @@ namespace Wabbajack.Lib.CompilationSteps
return file.RelativeTo(((MO2Compiler)_compiler).MO2ModsFolder).TopParent return file.RelativeTo(((MO2Compiler)_compiler).MO2ModsFolder).TopParent
.RelativeTo(((MO2Compiler)_compiler).MO2ModsFolder); .RelativeTo(((MO2Compiler)_compiler).MO2ModsFolder);
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IncludePatches")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludePatches(compiler);
}
}
} }
} }

View File

@ -33,20 +33,6 @@ namespace Wabbajack.Lib.CompilationSteps
} }
return result; return result;
}
public override IState GetState()
{
return new State();
}
[JsonObject("IncludePropertyFiles")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludePropertyFiles(compiler);
}
} }
} }
} }

View File

@ -24,26 +24,5 @@ namespace Wabbajack.Lib.CompilationSteps
result.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync()); result.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync());
return result; return result;
} }
public override IState GetState()
{
return new State(_pattern);
}
[JsonObject("IncludeRegex")]
public class State : IState
{
public string Pattern { get; set; }
public State(string pattern)
{
Pattern = pattern;
}
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeRegex(compiler, Pattern);
}
}
} }
} }

View File

@ -48,25 +48,5 @@ namespace Wabbajack.Lib.CompilationSteps
return null; return null;
} }
} }
public override IState GetState()
{
return new State(_game);
}
public class State : IState
{
private readonly SteamGame _game;
public State(SteamGame game)
{
_game = game;
}
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeSteamWorkshopItems(compiler, _game);
}
}
} }
} }

View File

@ -19,12 +19,6 @@ namespace Wabbajack.Lib.CompilationSteps
{ {
return Consts.ConfigFileExtensions.Contains(source.Path.Extension) ? await RemapFile(source) : null; return Consts.ConfigFileExtensions.Contains(source.Path.Extension) ? await RemapFile(source) : null;
} }
public override IState GetState()
{
return new State();
}
private async Task<Directive?> RemapFile(RawSourceFile source) private async Task<Directive?> RemapFile(RawSourceFile source)
{ {
var data = await source.AbsolutePath.ReadAllTextAsync(); var data = await source.AbsolutePath.ReadAllTextAsync();
@ -49,14 +43,5 @@ namespace Wabbajack.Lib.CompilationSteps
result.SourceDataID = await _compiler.IncludeFile(Encoding.UTF8.GetBytes(data)); result.SourceDataID = await _compiler.IncludeFile(Encoding.UTF8.GetBytes(data));
return result; return result;
} }
[JsonObject("IncludeStubbedConfigFiles")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeStubbedConfigFiles(compiler);
}
}
} }
} }

View File

@ -39,26 +39,5 @@ namespace Wabbajack.Lib.CompilationSteps
return null; return null;
} }
public override IState GetState()
{
return new State(_tag);
}
[JsonObject("IncludeTaggedMods")]
public class State : IState
{
public string Tag { get; set; }
public State(string tag)
{
Tag = tag;
}
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeTaggedMods(compiler, Tag);
}
}
} }
} }

View File

@ -34,11 +34,6 @@ namespace Wabbajack.Lib.CompilationSteps
} }
public override IState GetState()
{
return new State();
}
private async Task<byte[]> ReadAndCleanModlist(AbsolutePath absolutePath) private async Task<byte[]> ReadAndCleanModlist(AbsolutePath absolutePath)
{ {
var alwaysEnabled = _mo2Compiler.ModInis.Where(f => IgnoreDisabledMods.IsAlwaysEnabled(f.Value)) var alwaysEnabled = _mo2Compiler.ModInis.Where(f => IgnoreDisabledMods.IsAlwaysEnabled(f.Value))
@ -53,14 +48,5 @@ namespace Wabbajack.Lib.CompilationSteps
}).ToArray(); }).ToArray();
return Encoding.UTF8.GetBytes(string.Join("\r\n", lines)); return Encoding.UTF8.GetBytes(string.Join("\r\n", lines));
} }
[JsonObject("IncludeThisProfile")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeThisProfile(compiler);
}
}
} }
} }

View File

@ -0,0 +1,12 @@
namespace Wabbajack.Lib.CompilationSteps
{
public abstract class MO2CompilationStep : ACompilationStep
{
protected MO2CompilationStep(ACompiler compiler) : base(compiler)
{
}
public MO2Compiler MO2Compiler => (MO2Compiler)_compiler;
}
}

View File

@ -1,57 +0,0 @@
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Wabbajack.Common;
using File = Alphaleonis.Win32.Filesystem.File;
using Path = Alphaleonis.Win32.Filesystem.Path;
namespace Wabbajack.Lib.CompilationSteps
{
public class PatchStockESMs : ACompilationStep
{
private readonly MO2Compiler _mo2Compiler;
public PatchStockESMs(ACompiler compiler) : base(compiler)
{
_mo2Compiler = (MO2Compiler) compiler;
}
public override async ValueTask<Directive?> Run(RawSourceFile source)
{
var filename = source.Path.FileName;
var gameFile = _mo2Compiler.GamePath.Combine((RelativePath)"Data", filename);
if (!Consts.GameESMs.Contains(filename) || !source.Path.StartsWith("mods\\") ||
!gameFile.Exists) return null;
Utils.Log(
$"An ESM named {filename} was found in a mod that shares a name with one of the core game ESMs, it is assumed this is a cleaned ESM and it will be binary patched");
var result = source.EvolveTo<CleanedESM>();
result.SourceESMHash = _compiler.VFS.Index.ByRootPath[gameFile].Hash;
Utils.Status($"Generating patch of {filename}");
await using (var ms = new MemoryStream())
{
await Utils.CreatePatchCached(await gameFile.ReadAllBytesAsync(), await source.AbsolutePath.ReadAllBytesAsync(), ms);
var data = ms.ToArray();
result.SourceDataID = await _compiler.IncludeFile(data);
Utils.Log($"Generated a {data.Length} byte patch for {filename}");
}
return result;
}
public override IState GetState()
{
return new State();
}
[JsonObject("PatchStockESMs")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new PatchStockESMs(compiler);
}
}
}
}

View File

@ -577,6 +577,7 @@ namespace Wabbajack.Lib
new IgnoreGameFilesIfGameFolderFilesExist(this), new IgnoreGameFilesIfGameFolderFilesExist(this),
new IncludePropertyFiles(this), new IncludePropertyFiles(this),
new IncludeGenericGamePlugin(this), new IncludeGenericGamePlugin(this),
new IgnoreSaveFiles(this),
new IgnoreStartsWith(this,"logs\\"), new IgnoreStartsWith(this,"logs\\"),
new IgnoreStartsWith(this, "downloads\\"), new IgnoreStartsWith(this, "downloads\\"),
new IgnoreStartsWith(this,"webcache\\"), new IgnoreStartsWith(this,"webcache\\"),

View File

@ -199,20 +199,6 @@ namespace Wabbajack.Lib
return result; return result;
} }
public override IState GetState()
{
return new State();
}
[JsonObject("IncludeZEditPatches")]
public class State : IState
{
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeZEditPatches((MO2Compiler)compiler);
}
}
} }
public class zEditSettings public class zEditSettings

View File

@ -180,6 +180,32 @@ namespace Wabbajack.Test
Assert.False(extraFolder.Exists); Assert.False(extraFolder.Exists);
} }
[Fact]
public async Task SaveFilesAreIgnored()
{
var profile = utils.AddProfile();
var mod = await utils.AddMod("dummy");
var saveFolder = utils.MO2Folder.Combine("profiles", profile, "saves");
saveFolder.CreateDirectory();
await saveFolder.Combine("incompilation").WriteAllTextAsync("ignore this");
var installSaveFolderThisProfile = utils.InstallFolder.Combine("profiles", profile, "saves");
var installSaveFolderOtherProfile = utils.InstallFolder.Combine("profiles", "Other Profile", "saves");
installSaveFolderThisProfile.CreateDirectory();
installSaveFolderOtherProfile.CreateDirectory();
await installSaveFolderOtherProfile.Combine("otherprofile").WriteAllTextAsync("other profile file");
await installSaveFolderThisProfile.Combine("thisprofile").WriteAllTextAsync("this profile file");
await utils.Configure();
var modlist = await CompileAndInstall(profile);
Assert.Equal("other profile file", await installSaveFolderOtherProfile.Combine("otherprofile").ReadAllTextAsync());
Assert.Equal("this profile file", await installSaveFolderThisProfile.Combine("thisprofile").ReadAllTextAsync());
Assert.False(installSaveFolderThisProfile.Combine("incompilation").Exists);
}
[Fact] [Fact]
public async Task SetScreenSizeTest() public async Task SetScreenSizeTest()
{ {