/// <summary> /// Clears all buffers for this archive and causes any buffered data to be /// written to the underlying device. /// </summary> public void Flush() { long headerSize = GetHeaderSize(); do { var blocks = GetBlocks(); long maxheaderlength = ArchiveHelpers.FindSpace(blocks, blocks[0]); if (maxheaderlength < headerSize) { long newpos = ArchiveHelpers.FindOffset(blocks, blocks[1].Length, 512); ArchiveHelpers.MoveBytes(archive_.BaseStream, blocks[1].Offset, newpos, blocks[1].Length); ((IRageArchiveFileEntry7)blocks[1].Tag).FileOffset = (uint)(newpos / 512); blocks = GetBlocks(); maxheaderlength = ArchiveHelpers.FindSpace(blocks, blocks[0]); } else { break; } } while (true); // calculate key... var indexKey = GTA5Crypto.GetKeyIndex(FileName, (uint)archive_.BaseStream.Length); // archive_.key_ = GTA5Crypto.key_gta5; archive_.WriteHeader(GTA5Constants.PC_AES_KEY, GTA5Constants.PC_NG_KEYS[indexKey]); archive_.BaseStream.Flush(); }
public static RageArchiveWrapper7 Open(Stream stream, string fileName, bool leaveOpen = false) { var arch = new RageArchiveWrapper7(stream, fileName, leaveOpen); try { if (GTA5Constants.PC_LUT != null && GTA5Constants.PC_NG_KEYS != null) { // calculate key... var indexKey = GTA5Crypto.GetKeyIndex(arch.FileName, (uint)stream.Length); arch.archive_.ReadHeader(GTA5Constants.PC_AES_KEY, GTA5Constants.PC_NG_KEYS[indexKey]); // read... } else { arch.archive_.ReadHeader(GTA5Constants.PC_AES_KEY, null); // read... } return(arch); } catch { arch.Dispose(); throw; } }
public static RageArchiveWrapper7 Open(string fileName) { var finfo = new FileInfo(fileName); var fs = new FileStream(fileName, FileMode.Open); var arch = new RageArchiveWrapper7(fs, finfo.Name, false); try { if (GTA5Constants.PC_LUT != null && GTA5Constants.PC_NG_KEYS != null) { // calculate key... var indexKey = GTA5Crypto.GetKeyIndex(arch.FileName, (uint)finfo.Length); arch.archive_.ReadHeader(GTA5Constants.PC_AES_KEY, GTA5Constants.PC_NG_KEYS[indexKey]); // read... } else { arch.archive_.ReadHeader(GTA5Constants.PC_AES_KEY, null); // read... } return(arch); } catch { fs.Dispose(); arch.Dispose(); throw; } }
public static HashSet <string> GetAllStringsFromAllXmls(string gameDirectoryName) { var xmlStrings = new HashSet <string>(); ArchiveUtilities.ForEachBinaryFile(gameDirectoryName, (fullFileName, file, encryption) => { if (file.Name.EndsWith(".meta", StringComparison.OrdinalIgnoreCase) || file.Name.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)) { var fileStream = new MemoryStream(); file.Export(fileStream); var buf = new byte[fileStream.Length]; fileStream.Position = 0; fileStream.Read(buf, 0, buf.Length); if (file.IsEncrypted) { if (encryption == RageArchiveEncryption7.AES) { buf = AesEncryption.DecryptData(buf, GTA5Constants.PC_AES_KEY); } else { var indexKey = GTA5Crypto.GetKeyIndex(file.Name, (uint)file.UncompressedSize); buf = GTA5Crypto.Decrypt(buf, GTA5Constants.PC_NG_KEYS[indexKey]); } } if (file.IsCompressed) { var def = new DeflateStream(new MemoryStream(buf), CompressionMode.Decompress); var bufnew = new byte[file.UncompressedSize]; def.Read(bufnew, 0, (int)file.UncompressedSize); buf = bufnew; } var cleanedStream = new MemoryStream(buf); foreach (string xmlString in GetAllStringsFromXml(cleanedStream)) { xmlStrings.Add(xmlString); } Console.WriteLine(file.Name); } }); return(xmlStrings); }
/// <summary> /// Exports a file. /// </summary> public void Export(IArchiveFile file, string fileName) { if (file is IArchiveBinaryFile) { var binFile = (IArchiveBinaryFile)file; // export var ms = new MemoryStream(); file.Export(ms); ms.Position = 0; var buf = new byte[ms.Length]; ms.Position = 0; ms.Read(buf, 0, buf.Length); // decrypt... if (binFile.IsEncrypted) { var indexKey = GTA5Crypto.GetKeyIndex(binFile.Name, (uint)binFile.UncompressedSize); // TODO: if archive encrypted with AES, use AES key... buf = GTA5Crypto.Decrypt(buf, GTA5Constants.PC_NG_KEYS[indexKey]); } // decompress... if (binFile.IsCompressed) { var def = new DeflateStream(new MemoryStream(buf), CompressionMode.Decompress); var bufnew = new byte[binFile.UncompressedSize]; def.Read(bufnew, 0, (int)binFile.UncompressedSize); buf = bufnew; } File.WriteAllBytes(fileName, buf); } else { file.Export(fileName); } }
public static Tuple <Dictionary <int, PsoStructureInfo>, Dictionary <int, PsoEnumInfo> > GetAllStructureInfoAndEnumInfoFromPsoMetas(string gameDirectoryName) { Dictionary <int, PsoStructureInfo> structureInfos = new Dictionary <int, PsoStructureInfo>(); Dictionary <int, PsoEnumInfo> enumInfos = new Dictionary <int, PsoEnumInfo>(); ArchiveUtilities.ForEachBinaryFile(gameDirectoryName, (fullFileName, file, encryption) => { if (file.Name.EndsWith(".ymf") || file.Name.EndsWith(".ymt")) { var stream = new MemoryStream(); file.Export(stream); var buf = new byte[stream.Length]; stream.Position = 0; stream.Read(buf, 0, buf.Length); if (file.IsEncrypted) { if (encryption == RageArchiveEncryption7.AES) { buf = AesEncryption.DecryptData(buf, GTA5Constants.PC_AES_KEY); } else { var indexKey = GTA5Crypto.GetKeyIndex(file.Name, (uint)file.UncompressedSize); buf = GTA5Crypto.Decrypt(buf, GTA5Constants.PC_NG_KEYS[indexKey]); } } if (file.IsCompressed) { var def = new DeflateStream(new MemoryStream(buf), CompressionMode.Decompress); var bufnew = new byte[file.UncompressedSize]; def.Read(bufnew, 0, (int)file.UncompressedSize); buf = bufnew; } var cleanStream = new MemoryStream(buf); if (PsoFile.IsPSO(cleanStream)) { PsoFile pso = new PsoFile(); pso.Load(cleanStream); for (int i = 0; i < pso.DefinitionSection.Count; i++) { var id = pso.DefinitionSection.EntriesIdx[i]; var info = pso.DefinitionSection.Entries[i]; if (info is PsoStructureInfo structureInfo) { structureInfos.TryAdd(id.NameHash, structureInfo); } if (info is PsoEnumInfo enumInfo) { enumInfos.TryAdd(id.NameHash, enumInfo); } } Console.WriteLine(file.Name); } } }); return(new Tuple <Dictionary <int, PsoStructureInfo>, Dictionary <int, PsoEnumInfo> >(structureInfos, enumInfos)); }
public static HashSet <int> GetAllHashesFromPsoMetas(string gameDirectoryName) { var hashes = new HashSet <int>(); ArchiveUtilities.ForEachBinaryFile(gameDirectoryName, (fullFileName, file, encryption) => { if (file.Name.EndsWith(".ymf") || file.Name.EndsWith(".ymt")) { var stream = new MemoryStream(); file.Export(stream); var buf = new byte[stream.Length]; stream.Position = 0; stream.Read(buf, 0, buf.Length); if (file.IsEncrypted) { if (encryption == RageArchiveEncryption7.AES) { buf = AesEncryption.DecryptData(buf, GTA5Constants.PC_AES_KEY); } else { var indexKey = GTA5Crypto.GetKeyIndex(file.Name, (uint)file.UncompressedSize); buf = GTA5Crypto.Decrypt(buf, GTA5Constants.PC_NG_KEYS[indexKey]); } } if (file.IsCompressed) { var def = new DeflateStream(new MemoryStream(buf), CompressionMode.Decompress); var bufnew = new byte[file.UncompressedSize]; def.Read(bufnew, 0, (int)file.UncompressedSize); buf = bufnew; } var cleanStream = new MemoryStream(buf); if (PsoFile.IsPSO(cleanStream)) { PsoFile pso = new PsoFile(); pso.Load(cleanStream); foreach (var info in pso.DefinitionSection.EntriesIdx) { hashes.Add(info.NameHash); } foreach (var info in pso.DefinitionSection.Entries) { if (info is PsoStructureInfo) { var structureInfo = (PsoStructureInfo)info; foreach (var entryInfo in structureInfo.Entries) { hashes.Add(entryInfo.EntryNameHash); } } if (info is PsoEnumInfo) { var enumInfo = (PsoEnumInfo)info; foreach (var entryInfo in enumInfo.Entries) { hashes.Add(entryInfo.EntryNameHash); } } } Console.WriteLine(file.Name); } } }); return(hashes); }