public static IBSA Open(string filename) { var stream = new BufferedStream(new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite), 8 * 1024 * 1024); var checksumStopwatch = Stopwatch.StartNew(); byte[] checksum = MD5.Create().ComputeHash(stream); checksumStopwatch.Stop(); Debug.WriteLine( "MD5 checksum {0}\nTook {1}", BitConverter.ToString(checksum).Replace("-", string.Empty).ToLower(), checksumStopwatch.Elapsed ); stream.Seek(0, SeekOrigin.Begin); var reader = new BinaryReader(stream); var signature = (ArchiveSignature)reader.ReadUInt32(); var version = (ArchiveVersion)reader.ReadUInt32(); if (File.Exists(filename + ".xml")) { IBSA archive = null; using (var xmlReader = new StreamReader(string.Format("{0}.xml", filename))) { var serializer = new XmlSerializer(typeof(BSA)); try { archive = (IBSA)serializer.Deserialize(xmlReader); archive.Filename = filename; archive.SetStream(stream); } catch (InvalidOperationException ioe) { } } if (archive != null && ByteArrayCompare(checksum, archive.Checksum)) { return(archive); } else { Debug.WriteLine("Contents Changed, need recalculate"); } } stream.Close(); if (signature == ArchiveSignature.Oblivion && version == ArchiveVersion.Fallout3) { return(new Fo3Archive(filename)); } else { throw new UnsupportedArchiveException(signature, version); } }
private static void CreateAssetPatch(Settings settings, IBSA original, Fo3File originalRecord, Fo3File resultRecord, RecordAction recordAction) { string patchName; string patchFile; // @todo: memory stream and name with md5 using (var patchStream = new MemoryStream()) { // @todo: lock byte[] originalRecordBytes; if (original != null) { lock (original) { originalRecordBytes = originalRecord.GetData(original.Reader); } } else { originalRecordBytes = originalRecord.GetData(); } var referenceBytes = resultRecord.GetData(); BsDiff.Create(originalRecordBytes, referenceBytes, patchStream); patchStream.Seek(0, SeekOrigin.Begin); patchName = new Guid(MD5.Create().ComputeHash(patchStream)).ToString(); recordAction.PatchName = patchName; patchFile = string.Format("{0}\\{1}.patch", settings.GetTempFolder("Patches"), patchName); try { using (var fileStream = new FileStream(patchFile, FileMode.CreateNew)) { patchStream.Seek(0, SeekOrigin.Begin); patchStream.CopyTo(fileStream); } } catch (IOException exc) { // ignored } } }