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; } }
private void SaveARC(string path) { if (!Directory.Exists(path)) { WinFormsUtil.Error("Input path is not a Folder", path); return; } string folderName = Path.GetFileName(path); string parentName = Directory.GetParent(path).FullName; int type = CB_Repack.SelectedIndex; switch (type) { case 0: // AutoDetect { if (!folderName.Contains("_")) { WinFormsUtil.Alert("Unable to autodetect pack type."); return; } if (folderName.Contains("_g")) { goto case 1; } if (folderName.Contains("_d")) { goto case 2; } // else goto case 3; } case 1: // GARC Pack { if (threads > 0) { WinFormsUtil.Alert("Please wait for all operations to finish first."); return; } DialogResult dr = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Format Selection:", "Yes: Sun/Moon (Version 6)\nNo: XY/ORAS (Version 4)"); if (dr == DialogResult.Cancel) { return; } var version = dr == DialogResult.Yes ? GARC.VER_6 : GARC.VER_4; int padding = (int)NUD_Padding.Value; if (version == GARC.VER_4) { padding = 4; } string outfolder = Directory.GetParent(path).FullName; new Thread(() => { bool r = GarcUtil.PackGARC(path, Path.Combine(outfolder, folderName + ".garc"), version, padding, pBar1); if (!r) { WinFormsUtil.Alert("Packing failed."); return; } // Delete path after repacking if (CHK_Delete.Checked && Directory.Exists(path)) { Directory.Delete(path, true); } System.Media.SystemSounds.Asterisk.Play(); }).Start(); return; } case 2: // DARC Pack (from existing if exists) { string oldFile = path.Replace("_d", ""); if (File.Exists(Path.Combine(parentName, oldFile))) { oldFile = Path.Combine(parentName, oldFile); } else if (File.Exists(Path.Combine(parentName, oldFile + ".bin"))) { oldFile = Path.Combine(parentName, oldFile + ".bin"); } else if (File.Exists(Path.Combine(parentName, oldFile + ".darc"))) { oldFile = Path.Combine(parentName, oldFile + ".darc"); } else { oldFile = null; } bool r = Core.CTR.DARC.Files2darc(path, false, oldFile); if (!r) { WinFormsUtil.Alert("Packing failed."); } break; } case 3: // Mini Pack { // Get Folder Name string fileName = Path.GetFileName(path); if (fileName.Length < 3) { WinFormsUtil.Error("Mini Folder name not valid:", path); return; } int index = fileName.LastIndexOf('_'); string fileNum = fileName.Substring(0, index); string fileExt = fileName.Substring(index + 1); // Find old file for reference... string file; if (File.Exists(Path.Combine(parentName, fileNum + ".bin"))) { file = Path.Combine(parentName, fileNum + ".bin"); } else if (File.Exists(Path.Combine(parentName, fileNum + "." + fileExt))) { file = Path.Combine(parentName, fileNum + "." + fileExt); } else { file = null; } byte[] oldData = file != null?File.ReadAllBytes(file) : null; bool r = Mini.PackMini2(path, fileExt, Path.Combine(parentName, fileNum + "." + fileExt)); if (!r) { WinFormsUtil.Alert("Packing failed."); break; } // Check to see if the header size is different... if (oldData == null) // No data to compare to. { break; } byte[] newData = File.ReadAllBytes(Path.Combine(parentName, fileNum + "." + fileExt)); if (newData[2] == oldData[2]) { int newPtr = BitConverter.ToInt32(newData, 4); int oldPtr = BitConverter.ToInt32(oldData, 4); if (newPtr != oldPtr) // Header size is different. Prompt repointing. { if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Header size of existing file is nonstandard.", "Adjust newly packed file to have the same header size as old file? Data pointers will be updated accordingly.")) { break; } // Fix pointers byte[] update = Mini.AdjustMiniHeader(newData, oldPtr); File.WriteAllBytes(Path.Combine(parentName, fileNum + "." + fileExt), update); } } break; } default: WinFormsUtil.Alert("Repacking not implemented." + Environment.NewLine + path); return; } // Delete path after repacking if (CHK_Delete.Checked && Directory.Exists(path)) { Directory.Delete(path, true); } System.Media.SystemSounds.Asterisk.Play(); }
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 (BinaryReader bw = new BinaryReader(new FileStream(path, FileMode.Open))) 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(0x47415243))) // GARC { if (threads > 0) { WinFormsUtil.Alert("Please wait for all operations to finish first."); return; } bool SkipDecompression = ModifierKeys == Keys.Control; new Thread(() => { threads++; bool r = GarcUtil.garcUnpack(path, folderPath + "_g", SkipDecompression, pBar1); threads--; if (r) { batchRenameExtension(newFolder); } else { WinFormsUtil.Alert("Unpacking failed."); return; } System.Media.SystemSounds.Asterisk.Play(); }).Start(); return; } 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."); return; } } else if (!recursing) { WinFormsUtil.Alert("File is not a darc or a mini packed file:" + Environment.NewLine + path); return; } } catch (Exception e) { if (!recursing) { WinFormsUtil.Error("File error:" + Environment.NewLine + path, e.ToString()); } threads = 0; } System.Media.SystemSounds.Asterisk.Play(); }