mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
added patching support
This commit is contained in:
parent
e4ca3cd01e
commit
1466be47c0
@ -170,6 +170,7 @@ namespace Wabbajack.Common
|
|||||||
public dynamic IniData;
|
public dynamic IniData;
|
||||||
public string Name;
|
public string Name;
|
||||||
public string Meta;
|
public string Meta;
|
||||||
|
public string AbsolutePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -120,5 +120,14 @@ namespace Wabbajack.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] ReadAll(this Stream ins)
|
||||||
|
{
|
||||||
|
using (var ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
ins.CopyTo(ms);
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ namespace Wabbajack
|
|||||||
public Action<string, long, long> Progress_Function { get; }
|
public Action<string, long, long> Progress_Function { get; }
|
||||||
public List<Directive> InstallDirectives { get; private set; }
|
public List<Directive> InstallDirectives { get; private set; }
|
||||||
public List<Archive> SelectedArchives { get; private set; }
|
public List<Archive> SelectedArchives { get; private set; }
|
||||||
|
public List<RawSourceFile> AllFiles { get; private set; }
|
||||||
|
|
||||||
public List<IndexedArchive> IndexedArchives;
|
public List<IndexedArchive> IndexedArchives;
|
||||||
|
|
||||||
@ -111,6 +111,7 @@ namespace Wabbajack
|
|||||||
{
|
{
|
||||||
var info = metaname.FromJSON<IndexedArchive>();
|
var info = metaname.FromJSON<IndexedArchive>();
|
||||||
info.Name = Path.GetFileName(file);
|
info.Name = Path.GetFileName(file);
|
||||||
|
info.AbsolutePath = file;
|
||||||
|
|
||||||
var ini_name = file + ".meta";
|
var ini_name = file + ".meta";
|
||||||
if (ini_name.FileExists())
|
if (ini_name.FileExists())
|
||||||
@ -163,13 +164,13 @@ namespace Wabbajack
|
|||||||
.Where(p => p.FileExists())
|
.Where(p => p.FileExists())
|
||||||
.Select(p => new RawSourceFile() { Path = Path.Combine(Consts.GameFolderFilesDir, p.RelativeTo(GamePath)), AbsolutePath = p });
|
.Select(p => new RawSourceFile() { Path = Path.Combine(Consts.GameFolderFilesDir, p.RelativeTo(GamePath)), AbsolutePath = p });
|
||||||
|
|
||||||
var all_files = mo2_files.Concat(game_files).ToList();
|
AllFiles = mo2_files.Concat(game_files).ToList();
|
||||||
|
|
||||||
Info("Found {0} files to build into mod list", all_files.Count);
|
Info("Found {0} files to build into mod list", AllFiles.Count);
|
||||||
|
|
||||||
var stack = MakeStack();
|
var stack = MakeStack();
|
||||||
|
|
||||||
var results = all_files.AsParallel().Select(f => RunStack(stack, f)).ToList();
|
var results = AllFiles.AsParallel().Select(f => RunStack(stack, f)).ToList();
|
||||||
|
|
||||||
var nomatch = results.OfType<NoMatch>();
|
var nomatch = results.OfType<NoMatch>();
|
||||||
Info("No match for {0} files", nomatch.Count());
|
Info("No match for {0} files", nomatch.Count());
|
||||||
@ -179,11 +180,71 @@ namespace Wabbajack
|
|||||||
InstallDirectives = results.Where(i => !(i is IgnoredDirectly)).ToList();
|
InstallDirectives = results.Where(i => !(i is IgnoredDirectly)).ToList();
|
||||||
|
|
||||||
GatherArchives();
|
GatherArchives();
|
||||||
|
BuildPatches();
|
||||||
|
|
||||||
results.ToJSON("out.json");
|
results.ToJSON("out.json");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fills in the Patch fields in files that require them
|
||||||
|
/// </summary>
|
||||||
|
private void BuildPatches()
|
||||||
|
{
|
||||||
|
var groups = InstallDirectives.OfType<PatchedFromArchive>()
|
||||||
|
.GroupBy(p => p.ArchiveHash)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
Info("Patching building patches from {0} archives", groups.Count);
|
||||||
|
var absolute_paths = AllFiles.ToDictionary(e => e.Path, e => e.AbsolutePath);
|
||||||
|
Parallel.ForEach(groups, group => BuildArchivePatches(group.Key, group, absolute_paths));
|
||||||
|
|
||||||
|
if (InstallDirectives.OfType<PatchedFromArchive>().FirstOrDefault(f => f.Patch == null) != null)
|
||||||
|
{
|
||||||
|
Error("Missing patches after generation, this should not happen");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildArchivePatches(string archive_sha, IEnumerable<PatchedFromArchive> group, Dictionary<string, string> absolute_paths)
|
||||||
|
{
|
||||||
|
var archive = IndexedArchives.First(a => a.Hash == archive_sha);
|
||||||
|
var paths = group.Select(g => g.From).ToHashSet();
|
||||||
|
var streams = new Dictionary<string, MemoryStream>();
|
||||||
|
Info("Etracting Patch Files from {0}", archive.Name);
|
||||||
|
// First we fetch the source files from the input archive
|
||||||
|
using (var a = new ArchiveFile(archive.AbsolutePath))
|
||||||
|
{
|
||||||
|
a.Extract(entry =>
|
||||||
|
{
|
||||||
|
if (!paths.Contains(entry.FileName)) return null;
|
||||||
|
|
||||||
|
var result = new MemoryStream();
|
||||||
|
streams.Add(entry.FileName, result);
|
||||||
|
return result;
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
var extracted = streams.ToDictionary(k => k.Key, v => v.Value.ToArray());
|
||||||
|
// Now Create the patches
|
||||||
|
Parallel.ForEach(group, entry =>
|
||||||
|
{
|
||||||
|
Info("Patching {0}", entry.To);
|
||||||
|
var ss = extracted[entry.From];
|
||||||
|
using (var origin = new MemoryStream(ss))
|
||||||
|
using (var dest = File.OpenRead(absolute_paths[entry.To]))
|
||||||
|
using (var output = new MemoryStream())
|
||||||
|
{
|
||||||
|
var a = origin.ReadAll();
|
||||||
|
var b = dest.ReadAll();
|
||||||
|
BSDiff.Create(a, b, output);
|
||||||
|
entry.Patch = output.ToArray().ToBase64();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void GatherArchives()
|
private void GatherArchives()
|
||||||
{
|
{
|
||||||
var archives = IndexedArchives.GroupBy(a => a.Hash).ToDictionary(k => k.Key, k => k.First());
|
var archives = IndexedArchives.GroupBy(a => a.Hash).ToDictionary(k => k.Key, k => k.First());
|
||||||
|
Loading…
Reference in New Issue
Block a user