public static int Extract(List <string> args) { if (args.Count < 1) { Console.WriteLine("Usage: archive.hac folder-to-extract-to"); return(-1); } string infile = args[0]; string outdir = args.Count == 1 ? infile + ".ext" : args[1]; using (var archive = new HyoutaUtils.HyoutaArchive.HyoutaArchiveContainer(new DuplicatableFileStream(infile))) { Directory.CreateDirectory(outdir); for (long i = 0; i < archive.Filecount; ++i) { var f = archive.GetFile(i); using (var ds = f.DataStream.Duplicate()) using (var fs = new FileStream(Path.Combine(outdir, f.Filename ?? i.ToString("D8")), FileMode.Create)) { StreamUtils.CopyStream(ds, fs); } } } return(0); }
public static FileStorage.InitReturnValue InitializeAndPersistFileStorage(string baseDir, KnownFile[] knownFiles, ProgressReporter progress) { if (!Directory.Exists(baseDir)) { progress.Error(string.Format("No directory found at {0}.", baseDir)); return(null); } string backupArchivePath = Path.Combine(baseDir, "senpatcher_rerun_revert_data.bin"); FileStorage.InitReturnValue fileStoreReturnValue = null; using (HyoutaUtils.HyoutaArchive.HyoutaArchiveContainer backupArchive = TryLoadBackupArchive(backupArchivePath, progress)) { progress.Message("Reading and identifying game files..."); fileStoreReturnValue = FileStorage.InitializeFromKnownFiles(baseDir, knownFiles, backupArchive); } foreach (var perFileErrors in fileStoreReturnValue.Errors) { foreach (var errorMessage in perFileErrors.errors) { progress.Error(errorMessage); break; // only show first error to the user, this is really confusing otherwise } } if (fileStoreReturnValue.ShouldWriteBackupArchive) { progress.Message(string.Format("Writing backup archive to {0}...", backupArchivePath)); Stream ms = new MemoryStream(); fileStoreReturnValue.Storage.WriteToHyoutaArchive(ms); using (var fs = new FileStream(backupArchivePath, FileMode.Create)) { ms.Position = 0; HyoutaUtils.StreamUtils.CopyStream(ms, fs); } } return(fileStoreReturnValue); }