private Afs2Archive GetExternalAwbArchive() { var acbFileName = AcbFileName; var awbDirPath = Path.GetDirectoryName(acbFileName); if (awbDirPath == null) { awbDirPath = string.Empty; } var awbBaseFileName = Path.GetFileNameWithoutExtension(acbFileName); string[] awbFiles = null; string awbMask1 = null, awbMask2 = null, awbMask3 = null; if (awbFiles == null || awbFiles.Length < 1) { awbMask1 = string.Format(AwbFileNameFormats.Format1, awbBaseFileName); awbFiles = Directory.GetFiles(awbDirPath, awbMask1, SearchOption.TopDirectoryOnly); } if (awbFiles == null || awbFiles.Length < 1) { awbMask2 = string.Format(AwbFileNameFormats.Format2, awbBaseFileName); awbFiles = Directory.GetFiles(awbDirPath, awbMask2, SearchOption.TopDirectoryOnly); } if (awbFiles == null || awbFiles.Length < 1) { awbMask3 = string.Format(AwbFileNameFormats.Format3, awbBaseFileName); awbFiles = Directory.GetFiles(awbDirPath, awbMask3, SearchOption.TopDirectoryOnly); } if (awbFiles.Length < 1) { throw new FileNotFoundException($"Cannot find AWB file. Please verify corresponding AWB file is named '{awbMask1}', '{awbMask2}', or '{awbMask3}'."); } if (awbFiles.Length > 1) { throw new FileNotFoundException($"More than one matching AWB file for this ACB. Please verify only one AWB file is named '{awbMask1}', '{awbMask2}' or '{awbMask3}'."); } var externalAwbHash = GetFieldValueAsData(0, "StreamAwbHash"); var fs = File.Open(awbFiles[0], FileMode.Open, FileAccess.Read, FileShare.Read); var awbHash = AcbHelper.GetMd5Checksum(fs); if (!AcbHelper.AreDataIdentical(awbHash, externalAwbHash)) { Trace.WriteLine($"Checksum of AWB file '{fs.Name}' ({BitConverter.ToString(awbHash)}) does not match MD5 checksum inside ACB file '{acbFileName}' ({BitConverter.ToString(externalAwbHash)})."); } var archive = new Afs2Archive(fs, 0, fs.Name, true); archive.Initialize(); return(archive); }
internal virtual void Initialize() { var stream = _stream; var offset = _offset; var magic = stream.PeekBytes(offset, 4); magic = CheckEncryption(magic); if (!AcbHelper.AreDataIdentical(magic, UtfSignature)) { throw new FormatException($"'@UTF' signature (or its encrypted equivalent) is not found in '{_acbFileName}' at offset 0x{offset:x8}."); } using (var tableDataStream = GetTableDataStream()) { var header = GetUtfHeader(tableDataStream); _utfHeader = header; _rows = new Dictionary <string, UtfField> [header.RowCount]; if (header.TableSize > 0) { InitializeUtfSchema(stream, tableDataStream, 0x20); } } }
private byte[] CheckEncryption(byte[] magicBytes) { if (AcbHelper.AreDataIdentical(magicBytes, UtfSignature)) { _isEncrypted = false; _utfReader = new UtfReader(); return(magicBytes); } else { _isEncrypted = true; byte seed, increment; var keysFound = GetKeysForEncryptedUtfTable(magicBytes, out seed, out increment); if (!keysFound) { throw new FormatException($"Unable to decrypt UTF table at offset 0x{_offset:x8}"); } else { _utfReader = new UtfReader(seed, increment); } return(UtfSignature); } }
public static bool IsAfs2Archive(Stream stream, long offset) { var fileSignature = stream.PeekBytes(offset, 4); return(AcbHelper.AreDataIdentical(fileSignature, Afs2Signature)); }