public bool Extract(DataArchiveFile file, string destinationDirectory) { if (!_loaded) { Logger.Error($"Archive is not loaded"); return(false); } if (!Directory.Exists(destinationDirectory)) { Logger.Error($"Directory not found: {destinationDirectory}"); return(false); } DirectoryInfo destination = new DirectoryInfo(destinationDirectory); byte[] fileData = _sacBuffer.GetBytes(file.Offset, file.Size); string dir = Path.Combine(destination.FullName, file.Path); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } string path = Path.Combine(dir, file.Name); File.WriteAllBytes(path, fileData); Logger.Info($"Extract: {file.Id} {file.Path}{file.Name}"); return(true); }
public bool Load(string path) { Reset(); string saiPath = path + ".sai"; if (!File.Exists(saiPath)) { Logger.Error($".sai file not found: {saiPath}"); Reset(); return(false); } _saiFile = new FileInfo(saiPath); string sacPath = path + ".sac"; if (!File.Exists(sacPath)) { Logger.Error($".sac file not found: {sacPath}"); Reset(); return(false); } _sacFile = new FileInfo(sacPath); byte[] saiData = File.ReadAllBytes(_saiFile.FullName); IBuffer saiBuffer = new StreamBuffer(saiData); saiBuffer.SetPositionStart(); string magic = saiBuffer.ReadCString(); if (BafMagic != magic) { Logger.Error($"Invalid Magic File Bytes: {magic}"); Reset(); return(false); } int entries = saiBuffer.ReadInt32(); int fileNameSize = saiBuffer.ReadInt32(); int unk1 = saiBuffer.ReadInt32(); byte[] dataAttribs = saiBuffer.ReadBytes(entries * EntrySize); dataAttribs = DecryptData(Password, dataAttribs); byte[] dataFileNames = saiBuffer.ReadBytes(fileNameSize); dataFileNames = DecryptData(Password, dataFileNames); IBuffer nameBuffer = new StreamBuffer(dataFileNames); IBuffer attributeBuffer = new StreamBuffer(dataAttribs); attributeBuffer.SetPositionStart(); for (int i = 0; i < entries; i++) { DataArchiveFile item = new DataArchiveFile(); item.Id = attributeBuffer.ReadInt32(); item.Size = attributeBuffer.ReadInt32(); item.Offset = attributeBuffer.ReadInt32(); item.NameOffset = attributeBuffer.ReadInt32(); nameBuffer.Position = item.NameOffset; string filePath = nameBuffer.ReadCString(); filePath = filePath.Replace(BafDirectorySeparatorChar, Path.DirectorySeparatorChar); string fileName = Path.GetFileName(filePath); string directoryName = Path.GetDirectoryName(filePath); item.Name = fileName; item.Path = directoryName; _files.Add(item); } byte[] sacData = File.ReadAllBytes(_sacFile.FullName); _sacBuffer = new StreamBuffer(sacData); _sacBuffer.SetPositionStart(); _loaded = true; // decrypted StreamBuffer decSaiBuffer = new StreamBuffer(); decSaiBuffer.WriteCString(BafMagic); decSaiBuffer.WriteInt32(entries); decSaiBuffer.WriteInt32(dataFileNames.Length); decSaiBuffer.WriteInt32(0); decSaiBuffer.WriteBytes(dataAttribs); decSaiBuffer.WriteBytes(dataFileNames); File.WriteAllBytes(_saiFile.FullName + ".dec", decSaiBuffer.GetAllBytes()); return(true); }
public bool AddFile(string rootDirectory, string filePath) { if (_sacBuffer == null) { _sacBuffer = new StreamBuffer(); } FileInfo fileInfo = new FileInfo(filePath); if (!fileInfo.Exists) { return(false); } byte[] fileData = File.ReadAllBytes(fileInfo.FullName); int offset = _sacBuffer.Position; _sacBuffer.WriteBytes(fileData); string bafFilePath = filePath.Replace(rootDirectory, ""); string fileName = Path.GetFileName(bafFilePath); string directoryName = Path.GetDirectoryName(bafFilePath); if (directoryName == null) { directoryName = ""; bafFilePath = fileName; } else { directoryName = directoryName.Replace(Path.DirectorySeparatorChar, BafDirectorySeparatorChar); if (directoryName.StartsWith(BafDirectorySeparatorChar)) { directoryName = directoryName.Substring(1); } if (directoryName == string.Empty) { bafFilePath = fileName; } else { bafFilePath = directoryName + BafDirectorySeparatorChar + fileName; } } DataArchiveFile file = new DataArchiveFile(); file.Id = GetPathIndex(bafFilePath); file.Size = fileData.Length; file.Name = fileName; file.Path = directoryName; file.Offset = offset; file.NameOffset = NoNameOffset; _files.Add(file); Logger.Info($"Add: {file.Id} {file.Path}{file.Name}"); return(true); }