public static void unpackSFAR(DLCPackage dlc) { if (dlc == null || dlc.Files == null) { return; } string[] patt = { "pcc", "bik", "tfc", "afc", "cnd", "tlk", "bin", "dlc" }; string file = dlc.FileName; //full path string t1 = Path.GetDirectoryName(file); //cooked string t2 = Path.GetDirectoryName(t1); //DLC_Name string t3 = Path.GetDirectoryName(t2); //DLC string t4 = Path.GetDirectoryName(t3); //BioGame string gamebase = Path.GetDirectoryName(t4); //Mass Effect3 DebugOutput.PrintLn("Extracting DLC with gamebase : " + gamebase); DebugOutput.PrintLn("DLC name : " + t2); if (dlc.Files.Length > 1) { List <int> Indexes = new List <int>(); for (int i = 0; i < dlc.Files.Length; i++) { string DLCpath = dlc.Files[i].FileName; for (int j = 0; j < patt.Length; j++) { if (DLCpath.ToLower().EndsWith(patt[j].Trim().ToLower()) && patt[j].Trim().ToLower() != "") { string relPath = GetRelativePath(DLCpath); string outpath = gamebase + relPath; DebugOutput.PrintLn("Extracting file #" + i.ToString("d4") + ": " + outpath); if (!Directory.Exists(Path.GetDirectoryName(outpath))) { Directory.CreateDirectory(Path.GetDirectoryName(outpath)); } if (!File.Exists(outpath)) { using (FileStream fs = new FileStream(outpath, FileMode.Create)) dlc.DecompressEntryAsync(i, fs).Wait(); } Indexes.Add(i); Application.DoEvents(); break; } } } dlc.DeleteEntries(Indexes); } // AutoTOC AutoTOC.prepareToCreateTOC(t2 + "\\PCConsoleTOC.bin"); DebugOutput.PrintLn("DLC Done."); }
private bool HandleCommandLineArgs(string[] args, out int exitCode) { if (args.Length < 2) { exitCode = 0; return(false); } //automation try { if (args[1].Equals("-dlcinject")) { if (args.Length % 2 != 1 || args.Length < 5) { MessageBox.Show("Wrong number of arguments for the -dlcinject switch.:\nSyntax is: <exe> -dlcinject SFARPATH SEARCHTERM NEWFILEPATH [SEARCHTERM2 NEWFILEPATH2]...", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } string dlcFileName = args[2]; int numfiles = (args.Length - 3) / 2; string[] filesToReplace = new string[numfiles]; string[] newFiles = new string[numfiles]; int argnum = 3; //starts at 3 for (int i = 0; i < filesToReplace.Length; i++) { filesToReplace[i] = args[argnum]; argnum++; newFiles[i] = args[argnum]; argnum++; } if (File.Exists(dlcFileName)) { DLCPackage dlc = new DLCPackage(dlcFileName); for (int i = 0; i < numfiles; i++) { int idx = dlc.FindFileEntry(filesToReplace[i]); if (idx == -1) { MessageBox.Show("DLCEditor2 automator encountered an error: the file to replace does not exist.", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } dlc.ReplaceEntry(newFiles[i], idx); } exitCode = 0; return(true); } MessageBox.Show("Failed to autoinject: DLC file does not exist: " + dlcFileName, "ME3Explorer DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } else if (args[1].Equals("-dlcextract")) { if (args.Length != 5) { //-2 for me3explorer & -dlcextract MessageBox.Show("Wrong number of arguments for the -dlcextract switch.:\nSyntax is: <exe> -dlcextract SFARPATH SEARCHTERM EXTRACTIONPATH", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } string dlcFileName = args[2]; string searchTerm = args[3]; string extractionPath = args[4]; if (File.Exists(dlcFileName)) { DLCPackage dlc = new DLCPackage(dlcFileName); int idx = dlc.FindFileEntry(searchTerm); if (idx == -1) { MessageBox.Show("DLCEditor2 extraction automator encountered an error:\nThe file to replace does not exist or the tree has not been initialized.", "DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } using (FileStream fs = new FileStream(extractionPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true)) { dlc.DecompressEntryAsync(idx, fs).Wait(); } exitCode = 0; return(true); } MessageBox.Show("Failed to autoextract: DLC file does not exist: " + dlcFileName, "ME3Explorer DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } else if (args[1].Equals("-dlcaddfiles")) { if (args.Length % 2 != 1 || args.Length < 5) { MessageBox.Show("Wrong number of arguments for the -dlcaddfiles switch.:\nSyntax is: <exe> -dlcinject SFARPATH INTERNALPATH NEWFILEPATH [INTERNALPATH2 NEWFILEPATH2]...", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } string dlcFileName = args[2]; int numfiles = (args.Length - 3) / 2; string[] internalPaths = new string[numfiles]; string[] sourcePaths = new string[numfiles]; int argnum = 3; //starts at 3 for (int i = 0; i < internalPaths.Length; i++) { internalPaths[i] = args[argnum]; argnum++; sourcePaths[i] = args[argnum]; argnum++; } if (File.Exists(dlcFileName)) { DLCPackage dlc = new DLCPackage(dlcFileName); for (int i = 0; i < internalPaths.Length; i++) { dlc.AddFileQuick(sourcePaths[i], internalPaths[i]); } exitCode = 0; return(true); } MessageBox.Show("Failed to autoadd: DLC file does not exist: " + dlcFileName, "ME3Explorer DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } else if (args[1].Equals("-dlcremovefiles")) { if (args.Length < 4) { //-2 for me3explorer & -dlcextract MessageBox.Show("Wrong number of arguments for the -dlcremovefiles switch.:\nSyntax is: <exe> -dlcinject SFARPATH INTERNALPATH [INTERNALPATH2]...", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } string dlcFileName = args[2]; int numfiles = (args.Length - 3); string[] filesToRemove = new string[numfiles]; int argnum = 3; //starts at 3 for (int i = 0; i < filesToRemove.Length; i++) { filesToRemove[i] = args[argnum]; argnum++; } if (File.Exists(dlcFileName)) { DLCPackage dlc = new DLCPackage(dlcFileName); for (int i = 0; i < filesToRemove.Length; i++) { int idx = dlc.FindFileEntry(filesToRemove[i]); if (idx == -1) { MessageBox.Show("DLCEditor2 file removal automator encountered an error:\nThe file to remove does not exist or the tree has not been initialized.", "DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } dlc.DeleteEntry(idx); } exitCode = 0; return(true); } MessageBox.Show("Failed to autoremove: DLC file does not exist: " + dlcFileName, "ME3Explorer DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } else if (args[1].Equals("-dlcunpack") || args[1].Equals("-dlcunpack-nodebug")) { if (args.Length != 4) { MessageBox.Show("Wrong number of arguments for automated DLC unpacking:\nSyntax is: <exe> -dlcunpack SFARPATH EXTRACTIONPATH", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } string sfarPath = args[2]; string autoUnpackFolder = args[3]; if (File.Exists(sfarPath)) { DLCPackage dlc = new DLCPackage(sfarPath); if (args[1].Equals("-dlcunpack")) { //open debugging window since this operation takes a long time. KFreonLib.Debugging.DebugOutput.StartDebugger("DLC Editor 2"); } //Simulate Unpack operation click. SFAREditor2.unpackSFAR(dlc); exitCode = 0; return(true); } else { MessageBox.Show("Failed to autounpack: DLC file does not exist: " + sfarPath, "ME3Explorer DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } } else if (args[1].Equals("-toceditorupdate")) { //Legacy command requested by FemShep TOCeditor toc = new TOCeditor(); exitCode = toc.updateTOCFromCommandLine(args.Skip(2).ToList()); return(true); } else if (args[1].Equals("-autotoc")) { if (args.Length == 2) { AutoTOC.GenerateAllTOCs(); } else { AutoTOC.prepareToCreateTOC(args[2]); } exitCode = 0; return(true); } else if (args[1].Equals("-sfarautotoc")) { if (args.Length != 3) { MessageBox.Show("-sfarautotoc command line argument requires at least 1 parameter:\nSFARFILE.sfar", "Automated SFAR TOC Update Fail", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } var result = Parallel.For(2, args.Length, i => { if (args[i].EndsWith(".sfar") && File.Exists(args[i])) { DLCPackage DLC = new DLCPackage(args[2]); DLC.UpdateTOCbin(true); } }); exitCode = result.IsCompleted ? 0 : 1; return(true); } else if (args[1].Equals("-decompresspcc")) { if (args.Length != 4) { MessageBox.Show("-decompresspcc command line argument requires 2 parameters:\ninputfile.pcc outputfile.pcc\nBoth arguments can be the same.", "Auto Decompression Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } exitCode = PCCRepack.autoDecompressPcc(args[2], args[3]); return(true); } else if (args[1].Equals("-compresspcc")) { if (args.Length != 4) { MessageBox.Show("-compresspcc command line argument requires 2 parameters:\ninputfile.pcc outputfile.pcc\nBoth arguments can be the same.", "Auto Compression Error", MessageBoxButton.OK, MessageBoxImage.Error); exitCode = 1; return(true); } exitCode = PCCRepack.autoCompressPcc(args[2], args[3]); return(true); } } catch { exitCode = 1; return(true); } string ending = Path.GetExtension(args[1]).ToLower(); switch (ending) { case ".pcc": PackageEditor editor = new PackageEditor(); editor.Show(); editor.LoadFile(args[1]); break; } exitCode = 0; return(false); }
private void unpackSFARToolStripMenuItem_Click(object sender, EventArgs e) { if (DLC == null || DLC.Files == null) { return; } string result = "pcc; tfc; afc; cnd; tlk; bin; bik; dlc"; string unpackFolder; result = Microsoft.VisualBasic.Interaction.InputBox("Please enter pattern for unpacking, keep default to unpack everything.", "ME3 Explorer", "pcc; tfc; afc; cnd; tlk; bin; bik; dlc", 0, 0); if (result == "") { return; } DebugOutput.PrintLn("result : " + result); var dialog = new CommonOpenFileDialog(); dialog.IsFolderPicker = true; dialog.EnsurePathExists = true; dialog.Title = "Choose a folder to unpack to. Select ME3 directory to unpack to proper folder"; if (dialog.ShowDialog() == CommonFileDialogResult.Ok) { unpackFolder = dialog.FileName; } else { return; } if (!unpackFolder.EndsWith("\\")) { unpackFolder = unpackFolder + "\\"; } DebugOutput.PrintLn("Extracting DLC to : " + unpackFolder); result = result.Trim(); if (result.EndsWith(";")) { result = result.Substring(0, result.Length - 1); } string[] patt = result.Split(';'); string file = DLC.FileName; //full path string t1 = Path.GetDirectoryName(file); //cooked string t2 = Path.GetDirectoryName(t1); //DLC_Name string t3 = Path.GetDirectoryName(t2); //DLC string t4 = Path.GetDirectoryName(t3); //BioGame DebugOutput.PrintLn("DLC name : " + t2); if (DLC.Files.Length > 1) { List <int> Indexes = new List <int>(); for (int i = 0; i < DLC.Files.Length; i++) { string DLCpath = DLC.Files[i].FileName; for (int j = 0; j < patt.Length; j++) { if (DLCpath.ToLower().EndsWith(patt[j].Trim().ToLower()) && patt[j].Trim().ToLower() != "") { string relPath = GetRelativePath(DLCpath); string outpath = unpackFolder + relPath; DebugOutput.PrintLn("Extracting file #" + i.ToString("d4") + ": " + outpath); if (!Directory.Exists(Path.GetDirectoryName(outpath))) { Directory.CreateDirectory(Path.GetDirectoryName(outpath)); } using (FileStream fs = new FileStream(outpath, FileMode.Create)) DLC.DecompressEntry(i).WriteTo(fs); Indexes.Add(i); Application.DoEvents(); break; } } } DLC.DeleteEntries(Indexes); } // AutoTOC AutoTOC.prepareToCreateTOC(t2 + "\\PCConsoleTOC.bin"); MessageBox.Show("SFAR Unpacked."); }
private async void unpackDLCButton_Click(object sender, RoutedEventArgs e) { unpackDLCButton.IsEnabled = false; unpackDLCButton.Content = "Unpacking..."; string[] patt = { "pcc", "bik", "tfc", "afc", "cnd", "tlk", "bin", "dlc" }; string gamebase = ME3Directory.gamePath; taskBarItemInfo.ProgressState = TaskbarItemProgressState.Normal; unpackProgress.Maximum = totalUncompressedSize; taskBarItemInfo.ProgressValue = 0; timeRemainingTextBlock.Text = "Estimating Time Remaining..."; unpackOutput.AppendLine("DLC unpacking initiated..."); double uncompressedSoFar = 0; DateTime initial = DateTime.Now; foreach (var sfar in sfarsToUnpack) { string dlcName = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(sfar.FileName))); if (prettyDLCNames.ContainsKey(dlcName)) { dlcName = prettyDLCNames[dlcName]; } unpackOutput.AppendLine($"Unpacking {dlcName}..."); if (sfar.Files.Length > 1) { List <int> Indexes = new List <int>(); for (int i = 0; i < sfar.Files.Length; i++) { string DLCpath = sfar.Files[i].FileName; for (int j = 0; j < patt.Length; j++) { if (DLCpath.EndsWith(patt[j], StringComparison.OrdinalIgnoreCase)) { string outpath = gamebase + DLCpath.Replace("/", "\\"); if (!Directory.Exists(Path.GetDirectoryName(outpath))) { Directory.CreateDirectory(Path.GetDirectoryName(outpath)); } if (!File.Exists(outpath)) { using (FileStream fs = new FileStream(outpath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true)) { await sfar.DecompressEntryAsync(i, fs); } } Indexes.Add(i); uncompressedSoFar += sfar.Files[i].RealUncompressedSize; unpackProgress.Value = uncompressedSoFar; TimeSpan elapsed = DateTime.Now - initial; double percentComplete = uncompressedSoFar / totalUncompressedSize * 100; taskBarItemInfo.ProgressValue = percentComplete / 100.0; TimeSpan timeRemaining = TimeSpan.FromSeconds((elapsed.TotalSeconds / percentComplete) * (100 - percentComplete)); if (timeRemaining.TotalMinutes < 1) { timeRemainingTextBlock.Text = $"Estimated Time Remaining: < 1 minute"; } else { timeRemainingTextBlock.Text = string.Format("Estimated Time Remaining: {0:%h}h {0:%m}m", timeRemaining); } break; } } } sfar.DeleteEntries(Indexes); } unpackOutput.AppendLine($"{dlcName} unpacked"); } unpackOutput.AppendLine("Generating TOCs..."); await Task.Run(() => { AutoTOC.GenerateAllTOCs(); }); unpackOutput.AppendLine("ALL TOCs Generated!"); unpackOutput.AppendLine($"Elapsed time: {DateTime.Now - initial}"); unpackProgress.Value = unpackProgress.Maximum; taskBarItemInfo.ProgressState = TaskbarItemProgressState.None; completeStep2(); }