public GARCEntry(byte[] data) { Data = data; Accessed = true; if (data.Length == 0) { return; } if (data[0] != 0x11) { return; } try { using (MemoryStream newMS = new MemoryStream()) { LZSS.Decompress(new MemoryStream(data), data.Length, newMS); Data = newMS.ToArray(); } WasCompressed = true; } catch { } }
public static int garcUnpack(string garcPath, string outPath, bool skipDecompression) { if (!File.Exists(garcPath)) { throw new FileNotFoundException("File does not exist"); } // Unpack the GARC GARCFile garc = unpackGARC(garcPath); const string ext = "bin"; // Default Extension Name int fileCount = garc.fatb.FileCount; string format = "D" + Math.Ceiling(Math.Log10(fileCount)); if (outPath == "gametext") { format = "D3"; } FileCountDetermined?.Invoke(null, new FileCountDeterminedEventArgs { Total = fileCount }); using (BinaryReader br = new BinaryReader(File.OpenRead(garcPath))) { // Create Extraction folder if it does not exist. if (!Directory.Exists(outPath)) { Directory.CreateDirectory(outPath); } int filectr = 0; // Pull out all the files for (int o = 0; o < garc.fato.EntryCount; o++) { var Entry = garc.fatb.Entries[o]; // Set Entry File Name string fileName = o.ToString(format); #region OutDirectory Determination string parentFolder = Entry.IsFolder ? Path.Combine(outPath, fileName) : outPath; if (Entry.IsFolder) // Process Folder { Directory.CreateDirectory(parentFolder); } #endregion uint vector = Entry.Vector; for (int i = 0; i < 32; i++) // For each bit in vector { var SubEntry = Entry.SubEntries[i]; if (!SubEntry.Exists) { continue; } // Seek to Offset br.BaseStream.Position = SubEntry.Start + garc.DataOffset; // Check if Compressed bool compressed = false; if (!skipDecompression) { try { compressed = (byte)br.PeekChar() == 0x11; } catch { } } // Write File string fileOut = Path.Combine(parentFolder, (Entry.IsFolder ? i.ToString("00") : fileName) + "." + ext); using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(fileOut))) { // Write out the data for the file br.BaseStream.Position = SubEntry.Start + garc.DataOffset; bw.Write(br.ReadBytes(SubEntry.Length)); filectr++; } if (compressed) #region Decompression { string decout = Path.Combine(Path.GetDirectoryName(fileOut), "dec_" + Path.GetFileName(fileOut)); try { LZSS.Decompress(fileOut, decout); try { File.Delete(fileOut); } catch (Exception e) { throw new Exception("A compressed file could not be deleted: " + fileOut, e); } } catch { // File is really not encrypted. File.Delete(decout); } } #endregion UnpackProgressed?.Invoke(null, new UnpackProgressedEventArgs { Current = filectr, Total = fileCount }); if ((vector >>= 1) == 0) { break; } } } } return(fileCount); }