Can source game downloads from the game folder

This commit is contained in:
Timothy Baldridge 2020-05-02 15:09:29 -06:00
parent 589ef33160
commit 059f2ec96f
7 changed files with 80 additions and 14 deletions

View File

@ -85,7 +85,7 @@ namespace Wabbajack.Common
public AbsolutePath? TryGetGameLocation() public AbsolutePath? TryGetGameLocation()
{ {
return Consts.TestMode ? AbsolutePath.GetCurrentDirectory() : StoreHandler.Instance.TryGetGamePath(Game); return StoreHandler.Instance.TryGetGamePath(Game);
} }
public bool TryGetGameLocation(out AbsolutePath path) public bool TryGetGameLocation(out AbsolutePath path)

View File

@ -155,7 +155,7 @@ namespace Wabbajack.Common.StoreHandlers
if (!l.ContainsCaseInsensitive("\"installdir\"")) if (!l.ContainsCaseInsensitive("\"installdir\""))
return; return;
var path = new RelativePath($"common//{GetVdfValue(l)}").RelativeTo(u); var path = new RelativePath("common").Combine(GetVdfValue(l)).RelativeTo(u);
if (path.Exists) if (path.Exists)
game.Path = path; game.Path = path;
}); });

View File

@ -4,6 +4,7 @@ using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Reactive.Subjects; using System.Reactive.Subjects;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Wabbajack.Common; using Wabbajack.Common;
using Wabbajack.Lib.CompilationSteps; using Wabbajack.Lib.CompilationSteps;
@ -100,6 +101,15 @@ namespace Wabbajack.Lib
return id; return id;
} }
internal async Task<(RelativePath, AbsolutePath)> IncludeString(string str)
{
var id = IncludeId();
var fullPath = ModListOutputFolder.Combine(id);
await fullPath.WriteAllTextAsync(str);
return (id, fullPath);
}
public async Task<bool> GatherMetaData() public async Task<bool> GatherMetaData()
{ {
Utils.Log($"Getting meta data for {SelectedArchives.Count} archives"); Utils.Log($"Getting meta data for {SelectedArchives.Count} archives");

View File

@ -94,5 +94,10 @@ namespace Wabbajack.Lib.Downloaders
public abstract string? GetManifestURL(Archive a); public abstract string? GetManifestURL(Archive a);
public abstract string[] GetMetaIni(); public abstract string[] GetMetaIni();
public string GetMetaIniString()
{
return string.Join("\n", GetMetaIni());
}
} }
} }

View File

@ -46,13 +46,18 @@ namespace Wabbajack.Lib.Downloaders
public Game Game { get; set; } public Game Game { get; set; }
public RelativePath GameFile { get; set; } public RelativePath GameFile { get; set; }
public Hash Hash { get; set; } public Hash Hash { get; set; }
public string GameVersion { get; } public string GameVersion { get; set; } = "";
public State(string gameVersion) public State(string gameVersion)
{ {
GameVersion = gameVersion; GameVersion = gameVersion;
} }
public State()
{
}
[JsonIgnore] [JsonIgnore]
internal AbsolutePath SourcePath => Game.MetaData().GameLocation().Combine(GameFile); internal AbsolutePath SourcePath => Game.MetaData().GameLocation().Combine(GameFile);
@ -93,6 +98,7 @@ namespace Wabbajack.Lib.Downloaders
{ {
return new[] {"[General]", $"gameName={Game.MetaData().MO2ArchiveName}", $"gameFile={GameFile}"}; return new[] {"[General]", $"gameName={Game.MetaData().MO2ArchiveName}", $"gameFile={GameFile}"};
} }
} }
} }
} }

View File

@ -1,24 +1,17 @@
using Compression.BSA; using Compression.BSA;
using System; using System;
using System.Collections;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Alphaleonis.Win32.Filesystem;
using Wabbajack.Common; using Wabbajack.Common;
using Wabbajack.Lib.CompilationSteps; using Wabbajack.Lib.CompilationSteps;
using Wabbajack.Lib.Downloaders; using Wabbajack.Lib.Downloaders;
using Wabbajack.Lib.FileUploader; using Wabbajack.Lib.FileUploader;
using Wabbajack.Lib.NexusApi;
using Wabbajack.Lib.Validation; using Wabbajack.Lib.Validation;
using Directory = Alphaleonis.Win32.Filesystem.Directory; using Wabbajack.VirtualFileSystem;
using File = Alphaleonis.Win32.Filesystem.File;
using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo;
using Game = Wabbajack.Common.Game;
using Path = Alphaleonis.Win32.Filesystem.Path; using Path = Alphaleonis.Win32.Filesystem.Path;
namespace Wabbajack.Lib namespace Wabbajack.Lib
@ -105,7 +98,7 @@ namespace Wabbajack.Lib
var roots = new List<AbsolutePath> var roots = new List<AbsolutePath>
{ {
MO2Folder, GamePath, MO2DownloadsFolder MO2Folder, GamePath, MO2DownloadsFolder, CompilingGame.GameLocation()
}; };
// TODO: make this generic so we can add more paths // TODO: make this generic so we can add more paths
@ -172,6 +165,7 @@ namespace Wabbajack.Lib
UpdateTracker.NextStep("Pre-validating Archives"); UpdateTracker.NextStep("Pre-validating Archives");
// Find all Downloads
IndexedArchives = (await MO2DownloadsFolder.EnumerateFiles() IndexedArchives = (await MO2DownloadsFolder.EnumerateFiles()
.Where(f => f.WithExtension(Consts.MetaFileExtension).Exists) .Where(f => f.WithExtension(Consts.MetaFileExtension).Exists)
.PMap(Queue, async f => new IndexedArchive(VFS.Index.ByRootPath[f]) .PMap(Queue, async f => new IndexedArchive(VFS.Index.ByRootPath[f])
@ -182,6 +176,34 @@ namespace Wabbajack.Lib
})).ToList(); })).ToList();
var stockGameFolder = CompilingGame.GameLocation();
foreach (var (relativePath, hash) in await ClientAPI.GetGameFiles(CompilingGame.Game, Version.Parse(CompilingGame.InstalledVersion)))
{
if (!VFS.Index.ByRootPath.TryGetValue(relativePath.RelativeTo(stockGameFolder), out var virtualFile))
continue;
if (virtualFile.Hash != hash)
{
Utils.Log(
$"File {relativePath} int the game folder appears to be modified, it will not be used during compilation");
continue;
}
var state = new GameFileSourceDownloader.State
{
Game = CompilingGame.Game, GameVersion = CompilingGame.InstalledVersion, GameFile = relativePath
};
Utils.Log($"Adding Game file: {relativePath}");
IndexedArchives.Add(new IndexedArchive(virtualFile)
{
Name = (string)relativePath.FileName,
IniData = state.GetMetaIniString().LoadIniString(),
Meta = state.GetMetaIniString()
});
}
await CleanInvalidArchives(); await CleanInvalidArchives();
@ -395,11 +417,13 @@ namespace Wabbajack.Lib
await SelectedArchives.PMap(Queue, async a => await SelectedArchives.PMap(Queue, async a =>
{ {
var source = MO2DownloadsFolder.Combine(a.Name + Consts.MetaFileExtension); var source = MO2DownloadsFolder.Combine(a.Name + Consts.MetaFileExtension);
var ini = a.State.GetMetaIniString();
var (id, fullPath) = await IncludeString(ini);
InstallDirectives.Add(new ArchiveMeta InstallDirectives.Add(new ArchiveMeta
{ {
SourceDataID = await IncludeFile(source), SourceDataID = id,
Size = source.Size, Size = source.Size,
Hash = await source.FileHashAsync(), Hash = await fullPath.FileHashAsync(),
To = source.FileName To = source.FileName
}); });
}); });

View File

@ -422,6 +422,27 @@ namespace Wabbajack.Test
} }
[Fact]
public async Task CanSourceFilesFromStockGameFiles()
{
Consts.TestMode = false;
var profile = utils.AddProfile();
var mod = utils.AddMod();
var skyrimExe = utils.AddModFile(mod, @"Data\test.exe", 10);
await Game.SkyrimSpecialEdition.MetaData().GameLocation().Combine("SkyrimSE.exe").CopyToAsync(skyrimExe);
await utils.Configure();
await CompileAndInstall(profile);
utils.VerifyInstalledFile(mod, @"Data\test.exe");
Consts.TestMode = true;
}
[Fact] [Fact]
public async Task NoMatchIncludeIncludesNonMatchingFiles() public async Task NoMatchIncludeIncludesNonMatchingFiles()
{ {