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