예제 #1
0
        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;
        }
예제 #2
0
        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;
        }
예제 #3
0
        /// <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;
        }
예제 #4
0
        /// <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();
        }
예제 #5
0
        /// <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.");
            }
        }
예제 #6
0
        /// <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();
        }
예제 #7
0
        /// <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);

            }
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        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();
        }
예제 #11
0
        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;
        }