Exemple #1
0
            public IncludeZEditPatches(ACompiler compiler) : base(compiler)
            {
                var zEditPath = FindzEditPath(compiler);
                var havezEdit = zEditPath != null;

                Utils.Log(havezEdit ? $"Found zEdit at {zEditPath}" : $"zEdit not detected, disabling zEdit routines");

                if (!havezEdit)
                {
                    _mergesIndexed = new Dictionary <string, zEditMerge>();
                    return;
                }

                var merges = Directory.EnumerateFiles(Path.Combine(zEditPath, "profiles"),
                                                      DirectoryEnumerationOptions.Files | DirectoryEnumerationOptions.Recursive)
                             .Where(f => f.EndsWith("\\merges.json"))
                             .SelectMany(f => f.FromJSON <List <zEditMerge> >())
                             .GroupBy(f => (f.name, f.filename));

                merges.Where(m => m.Count() > 1)
                .Do(m =>
                {
                    Utils.Log(
                        $"WARNING, you have two patches named {m.Key.name}\\{m.Key.filename} in your zEdit profiles. We'll pick one at random, this probably isn't what you want.");
                });

                _mergesIndexed =
                    merges.ToDictionary(
                        m => Path.Combine(_mo2Compiler.MO2Folder, "mods", m.Key.name, m.Key.filename),
                        m => m.First());
            }
Exemple #2
0
        public static string FindzEditPath(ACompiler compiler)
        {
            _mo2Compiler = (MO2Compiler)compiler;
            var executables = _mo2Compiler.MO2Ini.customExecutables;

            if (executables.size == null)
            {
                return(null);
            }

            foreach (var idx in Enumerable.Range(1, int.Parse(executables.size)))
            {
                var path = (string)executables[$"{idx}\\binary"];
                if (path == null)
                {
                    continue;
                }

                if (path.EndsWith("zEdit.exe"))
                {
                    return(Path.GetDirectoryName(path));
                }
            }

            return(null);
        }
Exemple #3
0
 public ICompilationStep CreateStep(ACompiler compiler)
 {
     return(new IncludeZEditPatches(compiler));
 }
Exemple #4
0
        public void Build(ACompiler c, ModList lst)
        {
            MO2Compiler compiler = null;

            if (lst.ModManager == ModManager.MO2)
            {
                compiler = (MO2Compiler)c;
            }

            Text($"### {lst.Name} by {lst.Author} - Installation Summary");
            Text($"Build with Wabbajack Version {lst.WabbajackVersion}");
            Text(lst.Description);
            Text("#### Website:");
            NoWrapText($"[{lst.Website}]({lst.Website})");
            Text($"Mod Manager: {lst.ModManager.ToString()}");

            if (lst.ModManager == ModManager.MO2)
            {
                var readmeFile = Path.Combine(compiler?.MO2ProfileDir, "readme.md");
                if (File.Exists(readmeFile))
                {
                    File.ReadAllLines(readmeFile)
                    .Do(NoWrapText);
                }
            }

            var archiveCount = lst.Archives.Count + lst.Directives.Count(d => d is SteamMeta);
            var totalSize    = lst.Archives.Sum(a => a.Size);

            totalSize += lst.Directives.Where(d => d is SteamMeta).Cast <SteamMeta>().Sum(s => s.Size);

            Text(
                $"#### Download Summary ({archiveCount} archives - {totalSize.ToFileSizeString()})");
            foreach (var archive in SortArchives(lst.Archives))
            {
                var hash = archive.Hash.FromBase64().ToHex();
                NoWrapText(archive.State.GetReportEntry(archive));
                NoWrapText($"    * Size : {archive.Size.ToFileSizeString()}");
                NoWrapText($"    * SHA256 : [{hash}](https://www.virustotal.com/gui/file/{hash})");
            }
            lst.Directives.Where(d => d is SteamMeta).Do(f =>
            {
                if (!(f is SteamMeta s))
                {
                    return;
                }

                var link = $"https://steamcommunity.com/sharedfiles/filedetails/?id={s.ItemID}";
                var size = ((long)s.Size).ToFileSizeString();
                NoWrapText($"* Steam Workshop Item: [{s.ItemID}]({link}) | Size: {size}");
            });

            Text("\n\n");
            var patched = lst.Directives.OfType <PatchedFromArchive>().OrderBy(p => p.To).ToList();

            Text($"#### Summary of ({patched.Count}) patches");
            foreach (var directive in patched)
            {
                NoWrapText(
                    $"* Applying {SizeForID(directive.PatchID)} byte patch `{directive.FullPath}` to create `{directive.To}`");
            }


            var files = lst.Directives.OrderBy(d => d.To).ToList();

            Text($"\n\n### Install Plan of ({files.Count}) files");
            Text("(ignoring files that are directly copied from archives or listed in the patches section above)");
            foreach (var directive in files.OrderBy(f => f.GetType().Name).ThenByDescending(f => f.To))
            {
                switch (directive)
                {
                case PropertyFile i:
                    NoWrapText($"* `{i.SourceDataID}` as a `{Enum.GetName(typeof(PropertyType),i.Type)}`");
                    break;

                case FromArchive f:
                    //NoWrapText($"* `{f.To}` from `{f.FullPath}`");
                    break;

                case CleanedESM i:
                    NoWrapText($"* `{i.To}` by applying a patch to a game ESM ({i.SourceESMHash})");
                    break;

                case RemappedInlineFile i:
                    NoWrapText($"* `{i.To}` by remapping the contents of an inline file");
                    break;

                case InlineFile i:
                    NoWrapText($"* `{i.To}` from `{SizeForID(i.SourceDataID).ToFileSizeString()}` file included in modlist");
                    break;

                case CreateBSA i:
                    NoWrapText(
                        $"* `{i.To}` by creating a BSA of files found in `{Consts.BSACreationDir}\\{i.TempID}`");
                    break;
                }
            }

            var inlined = lst.Directives.OfType <InlineFile>()
                          .Select(f => (f.To, "inlined", SizeForID(f.SourceDataID)))
                          .Concat(lst.Directives
                                  .OfType <PatchedFromArchive>()
                                  .Select(f => (f.To, "patched", SizeForID(f.PatchID))))
                          .Distinct()
                          .OrderByDescending(f => f.Item3);

            NoWrapText("\n\n### Summary of inlined files in this installer");
            foreach (var inline in inlined)
            {
                NoWrapText($"* {inline.Item3.ToFileSizeString()} for {inline.Item2} file {inline.To}");
            }
        }