private void replaceFile(string filename, int n) { DLC.ReplaceEntry(filename, n); DLC = new DLCPackage(DLC.FileName); treeView1.Nodes.Clear(); treeView1.Nodes.Add(DLC.ToTree()); SearchNode(filename, treeView1.Nodes[0]); }
private void replaceFile(string filename, int n) { DLC.ReplaceEntry(filename, n); DLC = new DLCPackage(DLC.FileName); treeView1.Nodes.Clear(); // Todo: Add extension for toTree() // SFAR Editor 2 is useful for looking at non-PC SFARs //treeView1.Nodes.Add(DLC.ToTree()); SearchNode(filename, treeView1.Nodes[0]); }
private void replaceFile(String filename, int n) { DLC.ReplaceEntry(filename, n); DLC = new DLCPackage(DLC.MyFileName); treeView1.Nodes.Clear(); treeView1.Nodes.Add(DLC.ToTree()); SearchNode(filename, treeView1.Nodes[0]); if (!automated) { MessageBox.Show("File Replaced."); } else { System.Diagnostics.Debug.WriteLine("Injection complete."); } }
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 CompileIntoGame() { NamedBackgroundWorker nbw = new NamedBackgroundWorker(@"MixinManager CompileIntoGameThread"); List <string> failedApplications = new List <string>(); nbw.DoWork += (a, b) => { BottomLeftMessage = M3L.GetString(M3L.string_compilingMixins); OperationInProgress = true; //DEBUG STUFF #if DEBUG int numCoresToApplyWith = 1; #else var numCoresToApplyWith = Environment.ProcessorCount; if (numCoresToApplyWith > 4) { numCoresToApplyWith = 4; //no more than 4 as this uses a lot of memory } #endif var mixins = AvailableOfficialMixins.Where(x => x.UISelectedForUse).ToList(); MixinHandler.LoadPatchDataForMixins(mixins); //before dynamic void failedApplicationCallback(string str) { failedApplications.Add(str); } var compilingListsPerModule = MixinHandler.GetMixinApplicationList(mixins, failedApplicationCallback); if (failedApplications.Any()) { //Error building list Log.Information(@"Aborting mixin install due to incompatible selection of mixins"); return; } ProgressBarMax = mixins.Count(); ProgressBarValue = 0; int numdone = 0; void completedSingleApplicationCallback() { var val = Interlocked.Increment(ref numdone); ProgressBarValue = val; } //Mixins are ready to be applied Parallel.ForEach(compilingListsPerModule, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount > numCoresToApplyWith ? numCoresToApplyWith : Environment.ProcessorCount }, mapping => { var dlcFolderName = ModMakerCompiler.ModmakerChunkNameToDLCFoldername(mapping.Key.ToString()); //var outdir = Path.Combine(modpath, ModMakerCompiler.HeaderToDefaultFoldername(mapping.Key), @"CookedPCConsole"); //Directory.CreateDirectory(outdir); if (mapping.Key == ModJob.JobHeader.BASEGAME) { //basegame foreach (var file in mapping.Value) { try { using var vanillaPackageAsStream = VanillaDatabaseService.FetchBasegameFile(Mod.MEGame.ME3, Path.GetFileName(file.Key)); //packageAsStream.WriteToFile(@"C:\users\dev\desktop\compressed.pcc"); using var decompressedStream = MEPackage.GetDecompressedPackageStream(vanillaPackageAsStream, true); decompressedStream.Position = 0; var vanillaPackage = MEPackageHandler.OpenMEPackage(decompressedStream, $@"Vanilla - {Path.GetFileName(file.Key)}"); //decompressedStream.WriteToFile(@"C:\users\dev\desktop\decompressed.pcc"); using var mixinModifiedStream = MixinHandler.ApplyMixins(decompressedStream, file.Value, completedSingleApplicationCallback, failedApplicationCallback); mixinModifiedStream.Position = 0; var modifiedPackage = MEPackageHandler.OpenMEPackage(mixinModifiedStream, $@"Mixin Modified - {Path.GetFileName(file.Key)}"); // three way merge: get target stream var targetFile = Path.Combine(MEDirectories.CookedPath(SelectedInstallTarget), Path.GetFileName(file.Key)); var targetPackage = MEPackageHandler.OpenMEPackage(targetFile); var merged = ThreeWayPackageMerge.AttemptMerge(vanillaPackage, modifiedPackage, targetPackage); if (merged) { targetPackage.save(); Log.Information("Three way merge succeeded for " + targetFile); } else { Log.Error("Could not merge three way merge into " + targetFile); } //var outfile = Path.Combine(outdir, Path.GetFileName(file.Key)); //package.save(outfile, false); // don't compress //finalStream.WriteToFile(outfile); //File.WriteAllBytes(outfile, finalStream.ToArray()); } catch (Exception e) { var mixinsStr = string.Join(@", ", file.Value.Select(x => x.PatchName)); Log.Error($@"Error in mixin application for file {file.Key}: {e.Message}"); failedApplicationCallback(M3L.GetString(M3L.string_interp_errorApplyingMixinsForFile, mixinsStr, file.Key, e.Message)); } } } else { //dlc var dlcPackage = VanillaDatabaseService.FetchVanillaSFAR(dlcFolderName); //do not have to open file multiple times. var targetCookedPCDir = Path.Combine(MEDirectories.DLCPath(SelectedInstallTarget), dlcFolderName, @"CookedPCConsole"); var sfar = mapping.Key == ModJob.JobHeader.TESTPATCH ? Utilities.GetTestPatchPath(SelectedInstallTarget) : Path.Combine(targetCookedPCDir, @"Default.sfar"); bool unpacked = new FileInfo(sfar).Length == 32; DLCPackage targetDLCPackage = unpacked ? null : new DLCPackage(sfar); //cache SFAR target foreach (var file in mapping.Value) { try { using var vanillaPackageAsStream = VanillaDatabaseService.FetchFileFromVanillaSFAR(dlcFolderName, file.Key, forcedDLC: dlcPackage); using var decompressedStream = MEPackage.GetDecompressedPackageStream(vanillaPackageAsStream); decompressedStream.Position = 0; var vanillaPackage = MEPackageHandler.OpenMEPackage(decompressedStream, $@"VanillaDLC - {Path.GetFileName(file.Key)}"); using var mixinModifiedStream = MixinHandler.ApplyMixins(decompressedStream, file.Value, completedSingleApplicationCallback, failedApplicationCallback); mixinModifiedStream.Position = 0; var modifiedPackage = MEPackageHandler.OpenMEPackage(mixinModifiedStream, $@"Mixin Modified - {Path.GetFileName(file.Key)}"); // three way merge: get target stream // must see if DLC is unpacked first MemoryStream targetFileStream = null; //Packed if (unpacked) { targetFileStream = new MemoryStream(File.ReadAllBytes(Path.Combine(targetCookedPCDir, file.Key))); } else { targetFileStream = VanillaDatabaseService.FetchFileFromVanillaSFAR(dlcFolderName, Path.GetFileName(file.Key), forcedDLC: targetDLCPackage); } var targetPackage = MEPackageHandler.OpenMEPackage(targetFileStream, $@"Target package {dlcFolderName} - {file.Key}, from SFAR: {unpacked}"); var merged = ThreeWayPackageMerge.AttemptMerge(vanillaPackage, modifiedPackage, targetPackage); if (merged) { if (unpacked) { targetPackage.save(); Log.Information("Three way merge succeeded for " + targetPackage.FilePath); } else { var finalSTream = targetPackage.saveToStream(); targetDLCPackage.ReplaceEntry(finalSTream.ToArray(), targetDLCPackage.FindFileEntry(Path.GetFileName(file.Key))); Log.Information("Three way merge succeeded for " + targetPackage.FileSourceForDebugging); } } else { Log.Error("Could not merge three way merge into " + targetFileStream); } } catch (Exception e) { var mixinsStr = string.Join(@", ", file.Value.Select(x => x.PatchName)); Log.Error($@"Error in mixin application for file {file.Key}: {e.Message}"); failedApplicationCallback(M3L.GetString(M3L.string_interp_errorApplyingMixinsForFile, mixinsStr, file.Key, e.Message)); } //finalStream.WriteToFile(outfile); } } }); MixinHandler.FreeME3TweaksPatchData(); var percent = 0; //this is used to save a localization BottomLeftMessage = $"Running AutoTOC on game {percent}%"; //Run autotoc void tocingUpdate(int percent) { BottomLeftMessage = $"Running AutoTOC on game {percent}%"; } AutoTOC.RunTOCOnGameTarget(SelectedInstallTarget, tocingUpdate); //Generate moddesc //IniData ini = new IniData(); //ini[@"ModManager"][@"cmmver"] = App.HighestSupportedModDesc.ToString(CultureInfo.InvariantCulture); //prevent commas //ini[@"ModInfo"][@"game"] = @"ME3"; //ini[@"ModInfo"][@"modname"] = modname; //ini[@"ModInfo"][@"moddev"] = App.AppVersionHR; //ini[@"ModInfo"][@"moddesc"] = M3L.GetString(M3L.string_compiledFromTheFollowingMixins); //ini[@"ModInfo"][@"modver"] = @"1.0"; //generateRepaceFilesMapping(ini, modpath); //File.WriteAllText(Path.Combine(modpath, @"moddesc.ini"), ini.ToString()); }; nbw.RunWorkerCompleted += (a, b) => { OperationInProgress = false; ClearMixinHandler(); if (failedApplications.Count > 0) { var ld = new ListDialog(failedApplications, M3L.GetString(M3L.string_failedToApplyAllMixins), M3L.GetString(M3L.string_theFollowingMixinsFailedToApply), mainwindow); ld.ShowDialog(); } /*if (modpath != null) * { * OnClosing(new DataEventArgs(modpath)); * } * else * {*/ BottomLeftMessage = "Mixins installed, maybe. Check logs"; //} }; CompilePanelButton.IsOpen = false; nbw.RunWorkerAsync(); }