public void AddModToMerge(FileMerger.MergeSource source, Merge m) { var modFilePath = m.IsBundleContent ? source.Bundle.FullName : source.TextFile.FullName; var existingMod = m.Mods.Find(mod => mod.Name.EqualsIgnoreCase(source.Name)); if (existingMod != null) existingMod.Hash = Tools.Hasher.ComputeHash(modFilePath); else { m.Mods.Add( new FileHash { Hash = Tools.Hasher.ComputeHash(modFilePath), Name = source.Name }); } if (m.Category == Categories.Script) ScriptsChanged = true; else if (m.Category == Categories.Xml) XmlChanged = true; else if (m.IsBundleContent) BundleChanged = true; }
public void MergeByTreeNodesAsync( IEnumerable<TreeNode> fileNodesToMerge, string mergedModName) { _bgWorker.DoWork += (sender, e) => { _checkedFileNodes = fileNodesToMerge.ToArray(); _mergedModName = mergedModName; var checkedModNodesForFile = _checkedFileNodes.Select( fileNode => fileNode.GetTreeNodes().Where( modNode => modNode.Checked ).ToArray() ).ToArray(); ProgressInfo.TotalMergeCount = checkedModNodesForFile.Sum(modNodes => modNodes.Length - 1); ProgressInfo.TotalFileCount = _checkedFileNodes.Length; for (int i = 0; i < _checkedFileNodes.Length; ++i) { var fileNode = _checkedFileNodes[i]; ProgressInfo.CurrentFileName = Path.GetFileName(fileNode.Text); ProgressInfo.CurrentFileNum = i + 1; var checkedModNodes = checkedModNodesForFile[i]; ProgressInfo.CurrentAction = "Starting merge"; if (checkedModNodes.Any(node => (new LoadOrderComparer()).Compare(node.Text, _mergedModName) < 0) && !ConfirmRemainingConflict(_mergedModName)) continue; var isNew = false; var merge = _inventory.Merges.FirstOrDefault(m => m.RelativePath.EqualsIgnoreCase(fileNode.Text)); if (merge == null) { isNew = true; merge = new Merge { RelativePath = fileNode.Text, MergedModName = _mergedModName }; } if ((ModFileCategory)fileNode.Parent.Tag == Categories.BundleText) { merge.BundleName = Path.GetFileName(Paths.RetrieveMergedBundlePath()); MergeBundleFileNode(fileNode, checkedModNodes, merge, isNew); } else MergeFlatFileNode(fileNode, checkedModNodes, merge, isNew); } if (_bundleChanged) { var newBundlePath = PackNewBundle(Paths.RetrieveMergedBundlePath()); if (newBundlePath != null) { ProgressInfo.CurrentAction = "Adding bundle merge to inventory"; foreach (var bundleMerge in _pendingBundleMerges) _inventory.Merges.Add(bundleMerge); if (Program.Settings.Get<bool>("PlayCompletionSounds")) { System.Media.SystemSounds.Asterisk.Play(); } if (Program.Settings.Get<bool>("ReportAfterPack")) { using (var reportForm = new PackReportForm(newBundlePath)) { ProgressInfo.CurrentAction = "Showing pack report"; Program.MainForm.ShowModal(reportForm); } } } } CleanUpTempFiles(); CleanUpEmptyDirectories(); }; _bgWorker.RunWorkerAsync(); }
DialogResult HandleCanceledMerge(int remainingMergesForFile, Merge merge) { var msg = $"Merge {ProgressInfo.CurrentMergeNum} of {ProgressInfo.TotalMergeCount} was canceled."; var buttons = MessageBoxButtons.OK; if (remainingMergesForFile > 0) { var fileName = Path.GetFileName(merge.RelativePath); msg += $"\n\nContinue with {remainingMergesForFile} remaining merge{remainingMergesForFile.GetPluralS()} for file {fileName}?"; buttons = MessageBoxButtons.YesNo; } var result = Program.MainForm.ShowMessage(msg, "Skipped Merge", buttons, MessageBoxIcon.Information); if (result == DialogResult.No) { ProgressInfo.CurrentMergeNum += remainingMergesForFile; return DialogResult.Abort; } return DialogResult.OK; }
FileInfo MergeText(Merge merge, MergeSource source1, MergeSource source2) { ProgressInfo.CurrentAction = $"Merging {source1.Name} && {source2.Name} — waiting for KDiff3 to close"; var exitCode = KDiff3.Run(source1, source2, _vanillaFile, _outputPath); if (exitCode == 0) { if (!source1.TextFile.FullName.EqualsIgnoreCase(_outputPath) && !source1.TextFile.FullName.StartsWithIgnoreCase(Paths.MergedBundleContentAbsolute)) { _inventory.AddModToMerge(source1, merge); } if (!source2.TextFile.FullName.EqualsIgnoreCase(_outputPath) && !source2.TextFile.FullName.StartsWithIgnoreCase(Paths.MergedBundleContentAbsolute)) { _inventory.AddModToMerge(source2, merge); } if (Program.Settings.Get<bool>("PlayCompletionSounds")) { System.Media.SystemSounds.Asterisk.Play(); } if (Program.Settings.Get<bool>("ReportAfterMerge")) { using (var reportForm = new MergeReportForm( ProgressInfo.CurrentMergeNum, ProgressInfo.TotalMergeCount, source1.TextFile.FullName, source2.TextFile.FullName, _outputPath, source1.Name, source2.Name)) { ProgressInfo.CurrentAction = "Showing merge report"; Program.MainForm.ShowModal(reportForm); } } return new FileInfo(_outputPath); } else return null; }
void MergeBundleFileNode(TreeNode fileNode, TreeNode[] checkedModNodes, Merge merge, bool isNew) { _outputPath = Path.Combine(Paths.MergedBundleContent, fileNode.Text); if (File.Exists(_outputPath) && !ConfirmOutputOverwrite(_outputPath)) return; _vanillaFile = null; var metadata1 = checkedModNodes[0].GetMetadata(); var source1 = MergeSource.FromBundle(new FileInfo(metadata1.FilePath), metadata1.FileHash); for (int i = 1; i < checkedModNodes.Length; ++i) { ++ProgressInfo.CurrentMergeNum; var metadata2 = checkedModNodes[i].GetMetadata(); var source2 = MergeSource.FromBundle(new FileInfo(metadata2.FilePath), metadata2.FileHash); if (!GetUnpackedFiles(fileNode.Text, ref source1, ref source2)) { if (DialogResult.Abort != HandleCanceledMerge(checkedModNodes.Length - i - 1, merge)) continue; break; } var mergedFile = MergeText(merge, source1, source2); if (mergedFile != null) { source1 = MergeSource.FromFlatFile(mergedFile, null); } else if (DialogResult.Abort == HandleCanceledMerge(checkedModNodes.Length - i - 1, merge)) break; } if (merge.BundleName != null && isNew && merge.Mods.Count > 1) { _bundleChanged = true; _pendingBundleMerges.Add(merge); } }
void MergeFlatFileNode(TreeNode fileNode, TreeNode[] checkedModNodes, Merge merge, bool isNew) { var metadata1 = checkedModNodes[0].GetMetadata(); var source1 = MergeSource.FromFlatFile(new FileInfo(metadata1.FilePath), metadata1.FileHash); var relPath = Paths.GetRelativePath( source1.TextFile.FullName, Path.Combine(Paths.ModsDirectory, source1.Name)); _outputPath = Path.Combine(Paths.ModsDirectory, _mergedModName, relPath); if (File.Exists(_outputPath) && !ConfirmOutputOverwrite(_outputPath)) return; _vanillaFile = new FileInfo(fileNode.GetMetadata().FilePath); for (int i = 1; i < checkedModNodes.Length; ++i) { ++ProgressInfo.CurrentMergeNum; var metadata2 = checkedModNodes[i].GetMetadata(); var source2 = MergeSource.FromFlatFile(new FileInfo(metadata2.FilePath), metadata2.FileHash); var mergedFile = MergeText(merge, source1, source2); if (mergedFile != null) { source1 = MergeSource.FromFlatFile(mergedFile, null); } else if (DialogResult.Abort == HandleCanceledMerge(checkedModNodes.Length - i - 1, merge)) break; } if (isNew && merge.Mods.Count > 1) { ProgressInfo.CurrentAction = "Adding script merge to inventory"; _inventory.Merges.Add(merge); } }
public void MergeByTreeNodesAsync( IEnumerable <TreeNode> fileNodesToMerge, string mergedModName) { _bgWorker.DoWork += (sender, e) => { _checkedFileNodes = fileNodesToMerge.ToArray(); _mergedModName = mergedModName; var checkedModNodesForFile = _checkedFileNodes.Select( fileNode => fileNode.GetTreeNodes().Where( modNode => modNode.Checked ).ToArray() ).ToArray(); ProgressInfo.TotalMergeCount = checkedModNodesForFile.Sum(modNodes => modNodes.Length - 1); ProgressInfo.TotalFileCount = _checkedFileNodes.Length; for (int i = 0; i < _checkedFileNodes.Length; ++i) { var fileNode = _checkedFileNodes[i]; ProgressInfo.CurrentFileName = Path.GetFileName(fileNode.Text); ProgressInfo.CurrentFileNum = i + 1; var checkedModNodes = checkedModNodesForFile[i]; ProgressInfo.CurrentAction = "Starting merge"; if (checkedModNodes.Any(node => (new LoadOrderComparer()).Compare(node.Text, _mergedModName) < 0) && !ConfirmRemainingConflict(_mergedModName)) { continue; } var isNew = false; var merge = _inventory.Merges.FirstOrDefault(m => m.RelativePath.EqualsIgnoreCase(fileNode.Text)); if (merge == null) { isNew = true; merge = new Merge { RelativePath = fileNode.Text, MergedModName = _mergedModName }; } if ((ModFileCategory)fileNode.Parent.Tag == Categories.BundleText) { merge.BundleName = Path.GetFileName(Paths.RetrieveMergedBundlePath()); MergeBundleFileNode(fileNode, checkedModNodes, merge, isNew); } else { MergeFlatFileNode(fileNode, checkedModNodes, merge, isNew); } } if (_bundleChanged) { var newBundlePath = PackNewBundle(Paths.RetrieveMergedBundlePath()); if (newBundlePath != null) { ProgressInfo.CurrentAction = "Adding bundle merge to inventory"; foreach (var bundleMerge in _pendingBundleMerges) { _inventory.Merges.Add(bundleMerge); } if (Program.Settings.Get <bool>("PlayCompletionSounds")) { System.Media.SystemSounds.Asterisk.Play(); } if (Program.Settings.Get <bool>("ReportAfterPack")) { using (var reportForm = new PackReportForm(newBundlePath)) { ProgressInfo.CurrentAction = "Showing pack report"; Program.MainForm.ShowModal(reportForm); } } } } CleanUpTempFiles(); CleanUpEmptyDirectories(); }; _bgWorker.RunWorkerAsync(); }