/// <summary> /// Builds and saves a PFS image. /// </summary> /// <param name="p"></param> public void BuildPfs(PfsProperties p) { // TODO: Combine the superroot-specific stuff with the rest of the data block writing. // I think this is as simple as adding superroot and flat_path_table to allNodes hdr = new PfsHeader { BlockSize = p.BlockSize }; inodes = new List <PfsDinode32>(); dirents = new List <List <PfsDirent> >(); Console.WriteLine("Setting up root structure..."); SetupRootStructure(); BuildFSTree(root, p.proj, p.projDir); allDirs = root.GetAllChildrenDirs(); allFiles = root.GetAllChildrenFiles(); allNodes = new List <FSNode>(allDirs); allNodes.AddRange(allFiles); Console.WriteLine("Creating directory inodes ({0})...", allDirs.Count); addDirInodes(); Console.WriteLine("Creating file inodes ({0})...", allFiles.Count); addFileInodes(); Console.WriteLine("Creating flat_path_table..."); fpt = new FlatPathTable(allNodes); Console.WriteLine("Calculating data block layout..."); allNodes.Insert(0, root); CalculateDataBlockLayout(); Console.WriteLine("Writing image file..."); hdr.Ndblock = allFiles.Sum((f) => CeilDiv(f.Size, hdr.BlockSize)); { var stream = p.output; Console.WriteLine("Writing header..."); hdr.WriteToStream(stream); Console.WriteLine("Writing inodes..."); WriteInodes(stream); Console.WriteLine("Writing superroot dirents"); WriteSuperrootDirents(stream); Console.WriteLine("Writing flat_path_table"); stream.Position = fpt_ino.db[0] * hdr.BlockSize; fpt.WriteToStream(stream); Console.WriteLine("Writing data blocks..."); for (var x = 0; x < allNodes.Count; x++) { var f = allNodes[x]; stream.Position = f.ino.db[0] * hdr.BlockSize; WriteFSNode(stream, f); } } }
static void Main(string[] args) { switch (args[0]) { case "makepfs": { var proj = args[1]; var output = args[2]; var outFile = File.OpenWrite(output); var props = new LibOrbisPkg.PFS.PfsProperties { BlockSize = 65536, output = outFile, proj = Gp4Project.ReadFrom(File.OpenRead(proj)), projDir = Path.GetDirectoryName(proj) }; new PfsBuilder().BuildPfs(props); break; } case "makepkg": { var proj = args[1]; var project = Gp4Project.ReadFrom(File.OpenRead(proj)); var outputPath = args[2]; using (var outFile = File.Open( Path.Combine( outputPath, $"{project.volume.Package.ContentId}.pkg"), FileMode.Create)) { new PkgBuilder(project, Path.GetDirectoryName(proj)).Write(outFile); } break; } } }
/// <summary> /// Constructs a PfsBuilder with the given properties and logger. /// </summary> /// <param name="p">Properties for the image to be built</param> /// <param name="logger">Function that is called to report realtime PFS build status.</param> public PfsBuilder(PfsProperties p, Action <string> logger = null) { this.logger = logger; properties = p; Setup(); }