/// <summary> /// return gamefiles by hash for given qar /// does not include texture qars since it's currently only really used to look up fpks/archive files /// </summary> public static Dictionary <ulong, GameFile> GetQarGameFiles(string qarPath) { if (!File.Exists(qarPath)) { Debug.LogLine($"[GzsLib] File not found: {qarPath}"); throw new FileNotFoundException(); } else { string name = Path.GetFileName(qarPath); Debug.LogLine($"[GzsLib] Reading archive contents: {name}"); using (FileStream archiveFile = new FileStream(qarPath, FileMode.Open)) { var qarFiles = new Dictionary <ulong, GameFile>(); var qarFile = new QarFile(); qarFile.Name = Path.GetFileName(qarPath); qarFile.Read(archiveFile); foreach (QarEntry entry in qarFile.Entries) { qarFiles[entry.Hash] = new GameFile() { FilePath = entry.FilePath, FileHash = entry.Hash, QarFile = qarFile.Name }; } return(qarFiles); } } }
// Export QAR archive with specified parameters public static void WriteQarArchive(string FileName, string SourceDirectory, List <string> Files, uint Flags) { Debug.LogLine($"[GzsLib] Writing {Path.GetFileName(FileName)}"); List <QarEntry> qarEntries = new List <QarEntry>(); foreach (string s in Files) { if (s.EndsWith("_unknown")) { continue; } qarEntries.Add(new QarEntry() { FilePath = s, Hash = Tools.NameToHash(s), Compressed = (Path.GetExtension(s).EndsWith(".fpk") || Path.GetExtension(s).EndsWith(".fpkd")) ? true : false }); } QarFile q = new QarFile() { Entries = qarEntries, Flags = Flags, Name = FileName }; using (FileStream outFile = new FileStream(FileName, FileMode.Create)) { IDirectory fileDirectory = new FileSystemDirectory(SourceDirectory); q.Write(outFile, fileDirectory); } }
public void ReadQARArchive(string filePath, string outputDir) { IDirectory iDir = new FileSystemDirectory(outputDir); using (FileStream input = new FileStream(filePath, FileMode.Open)) { QarFile file = new QarFile(); file.Read(input); foreach (var exportedFile in file.ExportFiles(input)) { iDir.WriteFile(exportedFile.FileName, exportedFile.DataStream); // doesn't bother checking if the file already exists, since dats don't often have pre-existing stuff to overwrite. saved roughly 30 seconds when unpacking texture3 } } }
// Export QAR archive with specified parameters public static void WriteQarArchive(string FileName, string SourceDirectory, List <string> Files, uint Flags) { List <QarEntry> qarEntries = new List <QarEntry>(); foreach (string s in Files) { qarEntries.Add(new QarEntry() { FilePath = s, Hash = Tools.NameToHash(s), Compressed = Path.GetExtension(s).Contains(".fpk") ? true : false }); } QarFile q = new QarFile() { Entries = qarEntries, Flags = Flags, Name = FileName }; using (FileStream outFile = new FileStream(FileName, FileMode.Create)) { IDirectory fileDirectory = new FileSystemDirectory(SourceDirectory); q.Write(outFile, fileDirectory); } }
private static void Main(string[] args) { if (args.Length > 0 && args.Length <= 2) { if (args[0] == "-d") { if (args[1] == "-h") { Console.WriteLine(Hashing.HashFileName(args[2]).ToString("x")); } if (args[1] == "-hl") { Console.WriteLine(Hashing.HashFileNameLegacy(args[2]).ToString("x")); } if (args[1] == "-he") { Console.WriteLine(Hashing.HashFileExtension(args[2]).ToString("x")); } if (args[1] == "-hwe") { Console.WriteLine(Hashing.HashFileNameWithExtension(args[2]).ToString("x")); } return; } //if ends ReadDictionaries(); string path = args[0]; if (!Path.IsPathRooted(path)) { path = Path.GetFullPath(path); } //tex bool outputHashes = false; if (args.Length > 1) { if (args[1].ToLower() == "-outputhashes" || args[1].ToLower() == "-o") { outputHashes = true; } } if (File.Exists(path)) { string extension = Path.GetExtension(path); switch (extension) { case ".g0s": ReadArchive <GzsFile>(path); return; case ".dat": QarFile qarFile = ReadArchive <QarFile>(path, outputHashes); if (outputHashes) { HashSet <string> uniquePathHashes = new HashSet <string>(); HashSet <string> uniqueExtensionHashes = new HashSet <string>(); List <string> pathHashesRaw = new List <string>(); foreach (QarEntry entry in qarFile.Entries) { ulong pathHash = entry.Hash & 0x3FFFFFFFFFFFF; ulong extensionHash = entry.Hash >> 51; uniquePathHashes.Add(pathHash.ToString("x")); pathHashesRaw.Add(entry.Hash.ToString()); uniqueExtensionHashes.Add(extensionHash.ToString()); } List <string> pathHashes = uniquePathHashes.ToList <string>(); pathHashes.Sort(); string fileDirectory = Path.GetDirectoryName(path); string pathHashesOutputPath = Path.Combine(fileDirectory, string.Format("{0}_pathHashes.txt", Path.GetFileName(path))); File.WriteAllLines(pathHashesOutputPath, pathHashes); pathHashesOutputPath = Path.Combine(fileDirectory, string.Format("{0}_pathHashesRaw.txt", Path.GetFileName(path))); File.WriteAllLines(pathHashesOutputPath, pathHashesRaw); List <string> extensionHashes = uniqueExtensionHashes.ToList <string>(); extensionHashes.Sort(); string extensionHashesOutputPath = Path.Combine(fileDirectory, string.Format("{0}_extensionHashes.txt", Path.GetFileName(path))); File.WriteAllLines(extensionHashesOutputPath, extensionHashes); } return; case ".fpk": case ".fpkd": ReadArchive <FpkFile>(path); return; case ".pftxs": ReadArchive <PftxsFile>(path); return; case ".sbp": ReadArchive <SbpFile>(path); return; case ".xml": WriteArchive(path); return; } } else if (Directory.Exists(path)) { ReadFpkArchives(path); return; } } ShowUsageInfo(); }