public static uint[][][] ReadNgTables(string fileName) { uint[][][] result; var fs = new FileStream(fileName, FileMode.Open); var rd = new DataReader(fs); // 17 rounds... result = new uint[17][][]; for (int i = 0; i < 17; i++) { // 16 bytes... result[i] = new uint[16][]; for (int j = 0; j < 16; j++) { // 256 entries... result[i][j] = new uint[256]; for (int k = 0; k < 256; k++) { result[i][j][k] = rd.ReadUInt32(); } } } fs.Close(); return result; }
public static byte[][] ReadNgKeys(string fileName) { byte[][] result; var fs = new FileStream(fileName, FileMode.Open); var rd = new DataReader(fs); result = new byte[101][]; for (int i = 0; i < 101; i++) { result[i] = rd.ReadBytes(272); } fs.Close(); return result; }
/// <summary> /// Reads the archive header. /// </summary> public void ReadHeader(byte[] aesKey = null, byte[] ngKey = null) { var reader = new DataReader(BaseStream); var posbak = reader.Position; reader.Position = 0; uint header_identifier = reader.ReadUInt32(); // 0x52504637 if (header_identifier != IDENT) throw new Exception("The identifier " + header_identifier.ToString("X8") + " did not match the expected value of 0x52504637"); uint header_entriesCount = reader.ReadUInt32(); uint header_namesLength = reader.ReadUInt32(); uint header_encryption = reader.ReadUInt32(); byte[] entries_data_dec = null; byte[] names_data_dec = null; if (header_encryption == 0x04E45504F) // for OpenIV compatibility { // no encryption... Encryption = RageArchiveEncryption7.None; entries_data_dec = reader.ReadBytes(16 * (int)header_entriesCount); names_data_dec = reader.ReadBytes((int)header_namesLength); } else if (header_encryption == 0x0ffffff9) { // AES enceyption... Encryption = RageArchiveEncryption7.AES; var entries_data = reader.ReadBytes(16 * (int)header_entriesCount); entries_data_dec = AesEncryption.DecryptData(entries_data, aesKey); var names_data = reader.ReadBytes((int)header_namesLength); names_data_dec = AesEncryption.DecryptData(names_data, aesKey); } else { // NG encryption... Encryption = RageArchiveEncryption7.NG; var entries_data = reader.ReadBytes(16 * (int)header_entriesCount); entries_data_dec = GTA5Crypto.Decrypt(entries_data, ngKey); var names_data = reader.ReadBytes((int)header_namesLength); names_data_dec = GTA5Crypto.Decrypt(names_data, ngKey); } var entries_reader = new DataReader(new MemoryStream(entries_data_dec)); var names_reader = new DataReader(new MemoryStream(names_data_dec)); var entries = new List<IRageArchiveEntry7>(); for (var index = 0; index < header_entriesCount; index++) { entries_reader.Position += 4; int x = entries_reader.ReadInt32(); entries_reader.Position -= 8; if (x == 0x7fffff00) { // directory var e = new RageArchiveDirectory7(); e.Read(entries_reader); names_reader.Position = e.NameOffset; e.Name = names_reader.ReadString(); entries.Add(e); } else { if ((x & 0x80000000) == 0) { // binary file var e = new RageArchiveBinaryFile7(); e.Read(entries_reader); names_reader.Position = e.NameOffset; e.Name = names_reader.ReadString(); entries.Add(e); } else { // resource file var e = new RageArchiveResourceFile7(); e.Read(entries_reader); // there are sometimes resources with length=0xffffff which actually // means length>=0xffffff if (e.FileSize == 0xFFFFFF) { reader.Position = 512 * e.FileOffset; var buf = reader.ReadBytes(16); e.FileSize = ((uint)buf[7] << 0) | ((uint)buf[14] << 8) | ((uint)buf[5] << 16) | ((uint)buf[2] << 24); } names_reader.Position = e.NameOffset; e.Name = names_reader.ReadString(); entries.Add(e); } } } var stack = new Stack<RageArchiveDirectory7>(); stack.Push((RageArchiveDirectory7)entries[0]); Root = (RageArchiveDirectory7)entries[0]; while (stack.Count > 0) { var item = stack.Pop(); for (int index = (int)item.EntriesIndex; index < (item.EntriesIndex + item.EntriesCount); index++) { if (entries[index] is RageArchiveDirectory7) { item.Directories.Add(entries[index] as RageArchiveDirectory7); stack.Push(entries[index] as RageArchiveDirectory7); } else { item.Files.Add(entries[index]); } } } reader.Position = posbak; }
/// <summary> /// Reads the resource file entry. /// </summary> public void Read(DataReader reader) { NameOffset = reader.ReadUInt16(); var buf1 = reader.ReadBytes(3); FileSize = (uint)buf1[0] + (uint)(buf1[1] << 8) + (uint)(buf1[2] << 16); var buf2 = reader.ReadBytes(3); FileOffset = ((uint)buf2[0] + (uint)(buf2[1] << 8) + (uint)(buf2[2] << 16)) & 0x7FFFFF; SystemFlags = reader.ReadUInt32(); GraphicsFlags = reader.ReadUInt32(); }
/// <summary> /// Reads the binary file entry. /// </summary> public void Read(DataReader reader) { NameOffset = reader.ReadUInt16(); var buf1 = reader.ReadBytes(3); FileSize = (uint)buf1[0] + (uint)(buf1[1] << 8) + (uint)(buf1[2] << 16); var buf2 = reader.ReadBytes(3); FileOffset = (uint)buf2[0] + (uint)(buf2[1] << 8) + (uint)(buf2[2] << 16); FileUncompressedSize = reader.ReadUInt32(); switch (reader.ReadUInt32()) { case 0: IsEncrypted = false; break; case 1: IsEncrypted = true; break; default: throw new Exception("Error in RPF7 file entry."); } }
/// <summary> /// Reads the directory entry. /// </summary> public void Read(DataReader reader) { this.NameOffset = reader.ReadUInt32(); uint ident = reader.ReadUInt32(); if (ident != 0x7FFFFF00) throw new Exception("Error in RPF7 directory entry."); this.EntriesIndex = reader.ReadUInt32(); this.EntriesCount = reader.ReadUInt32(); }
/// <summary> /// Imports a file. /// </summary> public void Import(IArchiveDirectory directory, string fileName) { var fi = new FileInfo(fileName); var fs = new FileStream(fileName, FileMode.Open); var fsR = new DataReader(fs); var ident = fsR.ReadUInt32(); fs.Close(); // delete existing file var existingFile = directory.GetFile(fi.Name); if (existingFile != null) directory.DeleteFile(existingFile); if (ident == 0x07435352) { var newF = directory.CreateResourceFile(); newF.Name = fi.Name; newF.Import(fileName); } else { var newF = directory.CreateBinaryFile(); newF.Name = fi.Name; newF.Import(fileName); } }
/// <summary> /// Exports a resource file. /// </summary> public void Export(Stream stream) { // find version // -> http://dageron.com/?page_id=5446&lang=en var version = ((file.GraphicsFlags & 0xF0000000) >> 28) | ((file.SystemFlags & 0xF0000000) >> 24); var writer = new DataWriter(stream); writer.Write((uint)0x07435352); writer.Write((uint)version); writer.Write((uint)file.SystemFlags); writer.Write((uint)file.GraphicsFlags); var resourceStream = new PartialStream( archiveWrapper.archive_.BaseStream, delegate () // offset { return file.FileOffset * RageArchiveWrapper7.BLOCK_SIZE; }, delegate () // size { return file.FileSize; } ); var resourceReader = new DataReader(resourceStream); resourceReader.Position = 16; var buf = resourceReader.ReadBytes((int)resourceReader.Length - 16); writer.Write(buf); }
/// <summary> /// Imports a resource file. /// </summary> public void Import(Stream stream) { var resourceStream = new PartialStream( archiveWrapper.archive_.BaseStream, delegate () // offset { return file.FileOffset * RageArchiveWrapper7.BLOCK_SIZE; }, delegate () // size { return file.FileSize; }, delegate (long length) { archiveWrapper.RequestBytesRES(file, length); } ); resourceStream.SetLength(stream.Length); // read resource var reader = new DataReader(stream); var ident = reader.ReadUInt32(); var version = reader.ReadUInt32(); var systemFlags = reader.ReadUInt32(); var graphicsFlags = reader.ReadUInt32(); reader.Position = 0; var buffer = reader.ReadBytes((int)stream.Length); file.SystemFlags = systemFlags; file.GraphicsFlags = graphicsFlags; resourceStream.Write(buffer, 0, buffer.Length); }
public virtual void Load(Stream stream) { var reader = new DataReader(stream); reader.Position = 0; var ident = reader.ReadUInt32(); Version = reader.ReadInt32(); var systemFlags = reader.ReadUInt32(); var graphicsFlags = reader.ReadUInt32(); SystemPagesDiv16 = (int)(systemFlags >> 27) & 0x1; SystemPagesDiv8 = (int)(systemFlags >> 26) & 0x1; SystemPagesDiv4 = (int)(systemFlags >> 25) & 0x1; SystemPagesDiv2 = (int)(systemFlags >> 24) & 0x1; SystemPagesMul1 = (int)(systemFlags >> 17) & 0x7F; SystemPagesMul2 = (int)(systemFlags >> 11) & 0x3F; SystemPagesMul4 = (int)(systemFlags >> 7) & 0xF; SystemPagesMul8 = (int)(systemFlags >> 5) & 0x3; SystemPagesMul16 = (int)(systemFlags >> 4) & 0x1; SystemPagesSizeShift = (int)(systemFlags >> 0) & 0xF; var systemBaseSize = BASE_SIZE << SystemPagesSizeShift; var systemSize = systemBaseSize * SystemPagesDiv16 / 16 + systemBaseSize * SystemPagesDiv8 / 8 + systemBaseSize * SystemPagesDiv4 / 4 + systemBaseSize * SystemPagesDiv2 / 2 + systemBaseSize * SystemPagesMul1 * 1 + systemBaseSize * SystemPagesMul2 * 2 + systemBaseSize * SystemPagesMul4 * 4 + systemBaseSize * SystemPagesMul8 * 8 + systemBaseSize * SystemPagesMul16 * 16; GraphicsPagesDiv16 = (int)(graphicsFlags >> 27) & 0x1; GraphicsPagesDiv8 = (int)(graphicsFlags >> 26) & 0x1; GraphicsPagesDiv4 = (int)(graphicsFlags >> 25) & 0x1; GraphicsPagesDiv2 = (int)(graphicsFlags >> 24) & 0x1; GraphicsPagesMul1 = (int)(graphicsFlags >> 17) & 0x7F; GraphicsPagesMul2 = (int)(graphicsFlags >> 11) & 0x3F; GraphicsPagesMul4 = (int)(graphicsFlags >> 7) & 0xF; GraphicsPagesMul8 = (int)(graphicsFlags >> 5) & 0x3; GraphicsPagesMul16 = (int)(graphicsFlags >> 4) & 0x1; GraphicsPagesSizeShift = (int)(graphicsFlags >> 0) & 0xF; var graphicsBaseSize = BASE_SIZE << GraphicsPagesSizeShift; var graphicsSize = graphicsBaseSize * GraphicsPagesDiv16 / 16 + graphicsBaseSize * GraphicsPagesDiv8 / 8 + graphicsBaseSize * GraphicsPagesDiv4 / 4 + graphicsBaseSize * GraphicsPagesDiv2 / 2 + graphicsBaseSize * GraphicsPagesMul1 * 1 + graphicsBaseSize * GraphicsPagesMul2 * 2 + graphicsBaseSize * GraphicsPagesMul4 * 4 + graphicsBaseSize * GraphicsPagesMul8 * 8 + graphicsBaseSize * GraphicsPagesMul16 * 16; SystemData = new byte[systemSize]; GraphicsData = new byte[graphicsSize]; var deflateStream = new DeflateStream(stream, CompressionMode.Decompress, true); deflateStream.Read(SystemData, 0, systemSize); deflateStream.Read(GraphicsData, 0, graphicsSize); deflateStream.Close(); }
public static GTA5NGLUT[][] ReadNgLuts(string fileName) { GTA5NGLUT[][] result; var fs = new FileStream(fileName, FileMode.Open); var rd = new DataReader(fs); // 17 rounds... result = new GTA5NGLUT[17][]; for (int i = 0; i < 17; i++) { // 16 bytes... result[i] = new GTA5NGLUT[16]; for (int j = 0; j < 16; j++) { result[i][j] = new GTA5NGLUT(); // first compression step (2^32 -> 2^24) result[i][j].LUT0 = new byte[256][]; for (int k = 0; k < 256; k++) { //result[i][j].LUT0[k] = new byte[256]; //for (int l = 0; l < 256; l++) // result[i][j].LUT0[k][l] = rd.ReadByte(); result[i][j].LUT0[k] = rd.ReadBytes(256); } // second compression step (2^24 -> 2^16) result[i][j].LUT1 = new byte[256][]; for (int k = 0; k < 256; k++) { //result[i][j].LUT1[k] = new byte[256]; //for (int l = 0; l < 256; l++) // result[i][j].LUT1[k][l] = rd.ReadByte(); result[i][j].LUT1[k] = rd.ReadBytes(256); } // indices //result[i][j].Indices = new byte[65536]; //for (int k = 0; k < 65536; k++) // result[i][j].Indices[k] = rd.ReadByte(); result[i][j].Indices = rd.ReadBytes(65536); } } fs.Close(); return result; }