internal static void OpenARC(string path, ProgressBar pBar1, bool recursing = false) { string newFolder = ""; try { // Pre-check file length to see if it is at least valid. FileInfo fi = new FileInfo(path); if (fi.Length > (long)2 * (1 << 30)) { WinFormsUtil.Error("File is too big!"); return; } // 2 GB string folderPath = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path)); byte[] first4 = new byte[4]; try { using var fs = new FileStream(path, FileMode.Open); using var bw = new BinaryReader(fs); first4 = bw.ReadBytes(4); } catch (Exception e) { WinFormsUtil.Error("Cannot open file!", e.ToString()); } // Determine if it is a DARC or a Mini // Check if Mini first string fx = fi.Length > 10 * (1 << 20) ? null : Mini.GetIsMini(path); // no mini is above 10MB if (fx != null) // Is Mini Packed File { newFolder = folderPath + "_" + fx; // Fetch Mini File Contents Mini.UnpackMini(path, fx, newFolder, false); // Recurse throught the extracted contents if they extract successfully if (Directory.Exists(newFolder)) { foreach (string file in Directory.GetFiles(newFolder)) { OpenARC(file, pBar1, true); } BatchRenameExtension(newFolder); } } else if (first4.SequenceEqual(BitConverter.GetBytes(0x54594C41))) // ALYT { if (threads > 0) { WinFormsUtil.Alert("Please wait for all operations to finish first."); return; } new Thread(() => { Interlocked.Increment(ref threads); var alyt = new ALYT(File.ReadAllBytes(path)); var sarc = new SARC(alyt.Data) // rip out sarc { FileName = Path.GetFileNameWithoutExtension(path) + "_sarc", FilePath = Path.GetDirectoryName(path) }; if (!sarc.Valid) { return; } var files = sarc.Dump(); foreach (var _ in files) { // openARC(file, pBar1, true); } Interlocked.Decrement(ref threads); }).Start(); } else if (first4.SequenceEqual(BitConverter.GetBytes(0x47415243))) // GARC { if (threads > 0) { WinFormsUtil.Alert("Please wait for all operations to finish first."); return; } bool SkipDecompression = ModifierKeys == Keys.Control; new Thread(() => { Interlocked.Increment(ref threads); bool r = GarcUtil.UnpackGARC(path, folderPath + "_g", SkipDecompression, pBar1); Interlocked.Decrement(ref threads); if (r) { BatchRenameExtension(newFolder); } else { WinFormsUtil.Alert("Unpacking failed."); return; } System.Media.SystemSounds.Asterisk.Play(); }).Start(); } else if (ARC.Analyze(path).valid) // DARC { var data = File.ReadAllBytes(path); int pos = 0; while (BitConverter.ToUInt32(data, pos) != 0x63726164) { pos += 4; if (pos >= data.Length) { return; } } var darcData = data.Skip(pos).ToArray(); newFolder = folderPath + "_d"; bool r = Core.CTR.DARC.Darc2files(darcData, newFolder); if (!r) { WinFormsUtil.Alert("Unpacking failed."); } } else if (ARC.AnalyzeSARC(path).Valid) { var sarc = ARC.AnalyzeSARC(path); Console.WriteLine($"New SARC with {sarc.SFAT.EntryCount} files."); foreach (var _ in sarc.Dump(path)) { } } else if (!recursing) { WinFormsUtil.Alert("File is not a darc or a mini packed file:" + Environment.NewLine + path); } } catch (Exception e) { if (!recursing) { WinFormsUtil.Error("File error:" + Environment.NewLine + path, e.ToString()); } threads = 0; } }