Пример #1
0
        public IGameDataEntry GetEntry(string name)
        {
            var file = m_directory.GetFile(name);

            if (file != null)
            {
                if (file.Name.EndsWith(".rpf"))
                {
                    var binaryFile = (IArchiveBinaryFile)file;

                    return(new ArchiveDirectoryEntry(RageArchiveWrapper7.Open(binaryFile.GetStream(), binaryFile.Name).Root, binaryFile.Name));
                }

                return(new ArchiveFileEntry(file));
            }

            var directory = m_directory.GetDirectory(name);

            if (directory != null)
            {
                return(new ArchiveDirectoryEntry(directory));
            }

            throw new FileNotFoundException();
        }
Пример #2
0
        /// <summary>
        /// Opens an archive.
        /// </summary>
        public void Load(string fileName)
        {
            // close first...
            Close();

            this.archive  = RageArchiveWrapper7.Open(fileName);
            this.fileName = fileName;
        }
Пример #3
0
        private void RebuildArchive(string sourceArchiveFileName, string destinationArchiveFileName)
        {
            var fileInfo           = new FileInfo(sourceArchiveFileName);
            var fileStream         = new FileStream(sourceArchiveFileName, FileMode.Open);
            var sourceArchive      = RageArchiveWrapper7.Open(fileStream, fileInfo.Name);
            var destinationArchive = RageArchiveWrapper7.Create(destinationArchiveFileName);

            RebuildDictionary(sourceArchive.Root, destinationArchive.Root, sourceArchive.archive_.Encryption);
            destinationArchive.FileName            = fileInfo.Name;
            destinationArchive.archive_.Encryption = sourceArchive.archive_.Encryption;
            destinationArchive.Flush();
        }
Пример #4
0
        public static ArchiveDirectoryEntry GetFromCache(string path)
        {
            if (ms_archiveCache.TryGetValue(path, out var value))
            {
                return(value);
            }

            var entry = new ArchiveDirectoryEntry(RageArchiveWrapper7.Open(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read), Path.GetFileName(path)).Root, Path.GetFileName(path));

            ms_archiveCache.Add(path, entry);

            return(entry);
        }
Пример #5
0
        public static void ForEachFile(string gameDirectoryName, ProcessFileDelegate processDelegate)
        {
            var archiveFileNames = Directory.GetFiles(gameDirectoryName, "*.rpf", SearchOption.AllDirectories);

            for (int i = 0; i < archiveFileNames.Length; i++)
            {
                var fileName     = archiveFileNames[i];
                var fileInfo     = new FileInfo(fileName);
                var fileStream   = new FileStream(fileName, FileMode.Open);
                var inputArchive = RageArchiveWrapper7.Open(fileStream, fileInfo.Name);
                ForEachFile(fileName.Replace(gameDirectoryName, ""), inputArchive.Root, inputArchive.archive_.Encryption, processDelegate);
                inputArchive.Dispose();
            }
        }
Пример #6
0
        private void RebuildArchiveFile(IArchiveBinaryFile sourceFile, IArchiveDirectory destinationDirectory)
        {
            var fileStream   = sourceFile.GetStream();
            var inputArchive = RageArchiveWrapper7.Open(fileStream, sourceFile.Name);
            var newF         = destinationDirectory.CreateBinaryFile();

            newF.Name = sourceFile.Name;
            var outStream     = newF.GetStream();
            var outputArchive = RageArchiveWrapper7.Create(outStream, sourceFile.Name);

            RebuildDictionary(inputArchive.Root, outputArchive.Root, inputArchive.archive_.Encryption);
            outputArchive.FileName            = sourceFile.Name;
            outputArchive.archive_.Encryption = inputArchive.archive_.Encryption;
            outputArchive.Flush();
        }
Пример #7
0
 private static void ForEachFile(string fullPathName, IArchiveDirectory directory, RageArchiveEncryption7 encryption, ProcessFileDelegate processDelegate)
 {
     foreach (var file in directory.GetFiles())
     {
         processDelegate(fullPathName + "\\" + file.Name, file, encryption);
         if ((file is IArchiveBinaryFile) && file.Name.EndsWith(".rpf", StringComparison.OrdinalIgnoreCase))
         {
             var fileStream   = ((IArchiveBinaryFile)file).GetStream();
             var inputArchive = RageArchiveWrapper7.Open(fileStream, file.Name);
             ForEachFile(fullPathName + "\\" + file.Name, inputArchive.Root, inputArchive.archive_.Encryption, processDelegate);
         }
     }
     foreach (var subDirectory in directory.GetDirectories())
     {
         ForEachFile(fullPathName + "\\" + subDirectory.Name, subDirectory, encryption, processDelegate);
     }
 }
Пример #8
0
        public static void ForEachFile(string gameDirectoryName, ProcessFileDelegate processDelegate, ErrorDelegate errorDelegate = null)
        {
            var archiveFileNames = Directory.GetFiles(gameDirectoryName, "*.rpf", SearchOption.AllDirectories);

            for (int i = 0; i < archiveFileNames.Length; i++)
            {
                try
                {
                    var fileName     = archiveFileNames[i];
                    var inputArchive = RageArchiveWrapper7.Open(fileName);
                    ForEachFile(fileName.Replace(gameDirectoryName, ""), inputArchive.Root, inputArchive.archive_.Encryption, processDelegate);
                    inputArchive.Dispose();
                }
                catch (Exception e)
                {
                    errorDelegate?.Invoke(e);
                }
            }
        }
Пример #9
0
        public static void ForFile(string fullFileName, Action <IArchiveFile, RageArchiveEncryption7> cb)
        {
            fullFileName = fullFileName.Replace('/', '\\').Replace(Settings.Default.GTAFolder + "\\", "");
            string[] split = fullFileName.Split(new string[] { ".rpf" }, StringSplitOptions.None);

            for (int i = 0; i < split.Length - 1; i++)
            {
                split[i] = split[i] + ".rpf";
            }

            var baseRpf = Settings.Default.GTAFolder + "\\" + split[0];

            try
            {
                var fileInfo   = new FileInfo(baseRpf);
                var fileStream = new FileStream(baseRpf, FileMode.Open);

                var inputArchive = RageArchiveWrapper7.Open(fileStream, fileInfo.Name);

                ArchiveUtilities.ForEachFile(split[0], inputArchive.Root, inputArchive.archive_.Encryption, (string currFullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
                {
                    currFullFileName = currFullFileName.Replace('/', '\\');

                    if (currFullFileName == fullFileName)
                    {
                        cb(file, encryption);
                    }
                });

                inputArchive.Dispose();
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
            }
        }
Пример #10
0
        static void HandleExtractArchiveOptions(string[] args)
        {
            CommandLine.Parse <ExtractArchiveOptions>(args, (opts, gOpts) =>
            {
                EnsurePath();
                EnsureKeys();

                if (opts.InputFile == null)
                {
                    Console.WriteLine("Please provide input archive with -i --input");
                    return;
                }

                if (opts.OutputFolder == null)
                {
                    Console.WriteLine("Please provide output folder with -o --output");
                    return;
                }

                var fileInfo   = new FileInfo(opts.InputFile);
                var fileStream = new FileStream(opts.InputFile, FileMode.Open);

                var inputArchive = RageArchiveWrapper7.Open(fileStream, fileInfo.Name);

                var queue = new List <Tuple <string, RageArchiveWrapper7, bool> >()
                {
                    new Tuple <string, RageArchiveWrapper7, bool>(fileInfo.FullName, inputArchive, false)
                };

                while (queue.Count > 0)
                {
                    var fullPath    = queue[0].Item1;
                    var rpf         = queue[0].Item2;
                    var isTmpStream = queue[0].Item3;

                    queue.RemoveAt(0);

                    ArchiveUtilities.ForEachFile(fullPath.Replace(fileInfo.FullName, ""), rpf.Root, rpf.archive_.Encryption, (string fullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
                    {
                        string path = opts.OutputFolder + fullFileName;
                        string dir  = Path.GetDirectoryName(path);

                        if (!Directory.Exists(dir))
                        {
                            Directory.CreateDirectory(dir);
                        }

                        Console.WriteLine(fullFileName);

                        if (file.Name.EndsWith(".rpf"))
                        {
                            try
                            {
                                var tmpStream = new FileStream(Path.GetTempFileName(), FileMode.Open);

                                file.Export(tmpStream);
                                RageArchiveWrapper7 archive = RageArchiveWrapper7.Open(tmpStream, file.Name);
                                queue.Add(new Tuple <string, RageArchiveWrapper7, bool>(fullFileName, archive, true));
                            }
                            catch (Exception e)
                            {
                                Console.Error.WriteLine(e.Message);
                            }
                        }
                        else
                        {
                            if (file.Name.EndsWith(".xml") || file.Name.EndsWith(".meta"))
                            {
                                byte[] data = Utils.GetBinaryFileData((IArchiveBinaryFile)file, encryption);
                                string xml;

                                if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF)  // Detect BOM
                                {
                                    xml = Encoding.UTF8.GetString(data, 3, data.Length - 3);
                                }
                                else
                                {
                                    xml = Encoding.UTF8.GetString(data);
                                }

                                File.WriteAllText(path, xml, Encoding.UTF8);
                            }
                            else
                            {
                                file.Export(path);
                            }
                        }
                    });

                    var stream      = (FileStream)rpf.archive_.BaseStream;
                    string fileName = stream.Name;

                    rpf.Dispose();

                    if (isTmpStream)
                    {
                        File.Delete(fileName);
                    }
                }
            });
        }
Пример #11
0
        static void HandleFixArchiveOptions(string[] args)
        {
            CommandLine.Parse <FixArchiveOptions>(args, (opts, gOpts) =>
            {
                EnsurePath();
                EnsureKeys();

                if (opts.InputFiles != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        Console.WriteLine(fileInfo.FullName);

                        using (RageArchiveWrapper7 inputArchive = RageArchiveWrapper7.Open(fileInfo.FullName))
                        {
                            var rpfs = new List <Tuple <string, RageArchiveWrapper7> >();

                            if (opts.Recursive)
                            {
                                ArchiveUtilities.ForEachFile(fileInfo.FullName.Replace(Settings.Default.GTAFolder, ""), inputArchive.Root, inputArchive.archive_.Encryption, (string fullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
                                {
                                    if (fullFileName.EndsWith(".rpf", StringComparison.OrdinalIgnoreCase))
                                    {
                                        try
                                        {
                                            var binFile   = (RageArchiveBinaryFileWrapper7)file;
                                            var tmpStream = new FileStream(Path.GetTempFileName(), FileMode.Open);

                                            binFile.Export(tmpStream);
                                            RageArchiveWrapper7 archive = RageArchiveWrapper7.Open(tmpStream, file.Name);

                                            var wrapper = RageArchiveWrapper7.Open(tmpStream, binFile.Name);

                                            rpfs.Add(new Tuple <string, RageArchiveWrapper7>(fullFileName, wrapper));
                                        }
                                        catch (Exception e)
                                        {
                                            Console.Error.WriteLine(e.Message);
                                        }
                                    }
                                });

                                rpfs.Sort((a, b) =>
                                {
                                    return(b.Item1.Replace('\\', '/').Split('/').Length - a.Item1.Replace('\\', '/').Split('/').Length);
                                });
                            }

                            bool found = false;

                            if (opts.Recursive)
                            {
                                for (int j = 0; j < rpfs.Count; j++)
                                {
                                    var fullName = rpfs[j].Item1;
                                    var wrapper  = rpfs[j].Item2;

                                    if (wrapper.archive_.Encryption != RageArchiveEncryption7.None)
                                    {
                                        Console.WriteLine("SKIP " + fullName);
                                        continue;
                                    }

                                    found = true;

                                    wrapper.archive_.Encryption = RageArchiveEncryption7.NG;
                                    wrapper.Flush();
                                    wrapper.Dispose();

                                    Console.WriteLine("ENCRYPT " + fullName);
                                }
                            }

                            if (inputArchive.archive_.Encryption != RageArchiveEncryption7.None && !found)
                            {
                                Console.WriteLine("SKIP " + fileInfo.Name);
                                continue;
                            }

                            inputArchive.archive_.Encryption = RageArchiveEncryption7.NG;
                            inputArchive.Flush();
                            inputArchive.Dispose();

                            Console.WriteLine("ENCRYPT " + fileInfo.Name);

                            rpfs.Reverse();

                            for (int j = 0; j < rpfs.Count; j++)
                            {
                                rpfs[j].Item2.Dispose();
                            }
                        }
                    }
                }
            });
        }
Пример #12
0
        public static string[] GetDLCList()
        {
            Console.Error.WriteLine("Loading DLC list");

            var orderRegex    = new Regex("<order value=\"(\\d*)\"");
            var minOrderRegex = new Regex("<minOrder value=\"(\\d*)\"");
            var pathRegex     = new Regex(@"\\dlcpacks\\([a-z0-9_]*)\\");
            var pathRegex2    = new Regex(@"\\dlc_patch\\([a-z0-9_]*)\\");

            var dlclist   = new List <string>();
            var dlcOrders = new Dictionary <string, Tuple <int, int> >()
            {
                { "default", new Tuple <int, int>(0, 0) }
            };
            var fileName     = Settings.Default.GTAFolder + "\\update\\update.rpf";
            var fileInfo     = new FileInfo(fileName);
            var fileStream   = new FileStream(fileName, FileMode.Open);
            var inputArchive = RageArchiveWrapper7.Open(fileStream, fileInfo.Name);
            var doc          = new XmlDocument();

            ArchiveUtilities.ForEachFile(fileName.Replace(Settings.Default.GTAFolder, ""), inputArchive.Root, inputArchive.archive_.Encryption, (string fullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
            {
                if (fullFileName.EndsWith("dlclist.xml"))
                {
                    byte[] data = Utils.GetBinaryFileData((IArchiveBinaryFile)file, encryption);
                    string xml;

                    if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF)  // Detect BOM
                    {
                        xml = Encoding.UTF8.GetString(data, 3, data.Length - 3);
                    }
                    else
                    {
                        xml = Encoding.UTF8.GetString(data);
                    }

                    doc.LoadXml(xml);
                }
            });

            inputArchive.Dispose();


            ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (string fullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
            {
                if (fullFileName.EndsWith("setup2.xml") && !fullFileName.StartsWith("\\mods"))
                {
                    byte[] data = Utils.GetBinaryFileData((IArchiveBinaryFile)file, encryption);
                    string xml;

                    if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF)  // Detect BOM
                    {
                        xml = Encoding.UTF8.GetString(data, 3, data.Length - 3);
                    }
                    else
                    {
                        xml = Encoding.UTF8.GetString(data);
                    }

                    var matchOrder    = orderRegex.Match(xml);
                    var matchMinOrder = minOrderRegex.Match(xml);
                    var matchPath     = pathRegex.Match(fullFileName);
                    var matchPath2    = pathRegex2.Match(fullFileName);

                    var dlcName = matchPath.Success ? matchPath.Groups[1].Value : matchPath2.Groups[1].Value;

                    dlcOrders[dlcName] = new Tuple <int, int>(matchOrder.Success ? int.Parse(matchOrder.Groups[1].Value) : 0, matchMinOrder.Success ? int.Parse(matchMinOrder.Groups[1].Value) : 0);
                }
            });

            foreach (XmlNode pathsnode in doc.DocumentElement)
            {
                foreach (XmlNode itemnode in pathsnode.ChildNodes)
                {
                    string   p    = itemnode.InnerText.ToLowerInvariant();
                    string[] path = p.Split('/');

                    if (path.Length - 2 < 0)
                    {
                        Console.Error.WriteLine("Ignoring " + p);
                    }
                    else
                    {
                        dlclist.Add(path[path.Length - 2]);
                    }
                }
            }

            var kvp  = new List <KeyValuePair <string, Tuple <int, int> > >(); // dlc name => order, minOrder
            var list = new List <string>();

            foreach (var entry in dlcOrders)
            {
                kvp.Add(entry);
            }

            kvp.Sort((a, b) => {
                int test = a.Value.Item1 - b.Value.Item1;

                if (test == 0)
                {
                    return(dlclist.IndexOf(a.Key) - dlclist.IndexOf(b.Key));
                }
                else
                {
                    return(test);
                }
            });

            for (int i = 0; i < kvp.Count; i++)
            {
                list.Add(kvp[i].Key);
            }

            return(list.ToArray());
        }