Merge pull request #937 from wabbajack-tools/ignore-saves

Don't delete profile specific saves, don't include profile specific s…
This commit is contained in:
Timothy Baldridge 2020-07-01 07:06:22 -07:00 committed by GitHub
commit 898a50a7ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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 IsDirectory => Directory.Exists(_path);
public async Task DeleteDirectory()
public async Task DeleteDirectory(bool dontDeleteIfNotEmpty = false)
{
if (IsDirectory)
{
if (dontDeleteIfNotEmpty && (EnumerateFiles().Any() || EnumerateDirectories().Any())) return;
await Utils.DeleteDirectory(this);
}
}

View File

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

View File

@ -12,6 +12,5 @@ namespace Wabbajack.Lib.CompilationSteps
}
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)
{
if (!Consts.SupportedBSAs.Contains(source.Path.Extension)) return null;
@ -108,14 +103,5 @@ namespace Wabbajack.Lib.CompilationSteps
await _cleanup();
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;
}
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";
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
{
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;
}
public override IState GetState()
{
return new State();
}
public static bool IsAlwaysEnabled(dynamic data)
{
if (data == null)
@ -53,14 +48,5 @@ namespace Wabbajack.Lib.CompilationSteps
return true;
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;
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";
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;
}
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;
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;
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;
}
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";
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());
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());
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());
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());
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());
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());
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";
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

@ -113,19 +113,5 @@ namespace Wabbajack.Lib.CompilationSteps
return file.RelativeTo(((MO2Compiler)_compiler).MO2ModsFolder).TopParent
.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;
}
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());
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;
}
}
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;
}
public override IState GetState()
{
return new State();
}
private async Task<Directive?> RemapFile(RawSourceFile source)
{
var data = await source.AbsolutePath.ReadAllTextAsync();
@ -49,14 +43,5 @@ namespace Wabbajack.Lib.CompilationSteps
result.SourceDataID = await _compiler.IncludeFile(Encoding.UTF8.GetBytes(data));
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;
}
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)
{
var alwaysEnabled = _mo2Compiler.ModInis.Where(f => IgnoreDisabledMods.IsAlwaysEnabled(f.Value))
@ -53,14 +48,5 @@ namespace Wabbajack.Lib.CompilationSteps
}).ToArray();
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 IncludePropertyFiles(this),
new IncludeGenericGamePlugin(this),
new IgnoreSaveFiles(this),
new IgnoreStartsWith(this,"logs\\"),
new IgnoreStartsWith(this, "downloads\\"),
new IgnoreStartsWith(this,"webcache\\"),

View File

@ -199,20 +199,6 @@ namespace Wabbajack.Lib
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

View File

@ -180,6 +180,32 @@ namespace Wabbajack.Test
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]
public async Task SetScreenSizeTest()
{