Exemplo n.º 1
0
        private static async Task <string[]> CookFiles(VFS vfs, AbsolutePath to, bool trial = false)
        {
            var files = vfs.AllAppliedFiles.Select(f => f.First()).OfType <ModFile>()
                        .Where(f => Definitions.BatchForExtension.ContainsKey(f.Path.Extension))
                        .GroupIntoSizes(f => f.Size, Definitions.MaxBatchSize)
                        .Select((itms, idx) => (itms, idx))
                        .ToArray();

            List <string> newEsps = new();

            Console.WriteLine($"Found {files.Length} archives to build");
            foreach (var(group, idx) in files)
            {
                var name    = $"_Cooked {idx:0000}.bsa";
                var outFile = to.Combine("mods", "Cooked Files", name);
                if (!trial)
                {
                    Console.WriteLine($"Building {name}");
                    var flags = group.Select(f => Definitions.BatchForExtension[f.Path.Extension]).Distinct()
                                .Aggregate((uint)0, (a, b) => a | (uint)b.FileFlags);
                    await using var bsa = await BSABuilder.Create(new BSAStateObject ()
                    {
                        ArchiveFlags = ((int)(ArchiveFlags.HasFileNames | ArchiveFlags.HasFolderNames
                                              /* | ArchiveFlags.HasFileNameBlobs*/)) | 0x10 | 0x80,
                        FileFlags = flags,
                        Magic     = Encoding.ASCII.GetString(new byte[] { 0x42, 0x53, 0x41, 0x00 }),
                        Version   = 0x67
                    }, Definitions.MaxBatchSize);

                    bsa.HeaderType = VersionType.SSE;

                    foreach (var(file, fidx) in group.Select((itm, fidx) => (itm, fidx)))
                    {
                        var state = new BSAFileStateObject
                        {
                            Path            = (RelativePath)((string)file.Path).ToLowerInvariant().Replace('/', '\\'),
                            Index           = fidx,
                            FlipCompression = false
                        };
                        await bsa.AddFile(state, await file.AbsolutePath.OpenRead());
                    }

                    Console.WriteLine($"Writing {name}");

                    await bsa.Build(outFile);

                    Console.WriteLine($"Done building {name}");
                }

                Console.WriteLine($"Writing Stub");
                outFile = outFile.ReplaceExtension(new Extension(".esp"));
                newEsps.Add(outFile.FileName.ToString());
                await "Stub.esp".RelativeTo(AbsolutePath.EntryPoint).CopyToAsync(outFile);
            }

            return(newEsps.ToArray());
        }