/// <summary> /// Class constructor /// </summary> /// <param name="conflicts">The list of file conflicts.</param> public OverwriteWarningsForm(OverwriteWarningCollection warnings, bool fatal, OverwriteWarningType type) { // // Required for Windows Form Designer support // InitializeComponent(); pictureBox.Image = SystemIcons.Exclamation.ToBitmap(); // There appears to be a bug in the 1.0 version of the framework. On my // 3.2ghz machine, if listBox.Items.Add(conflict) is placed in the // foreach array it hangs, unless you slow it down somehow. Moving // the add outside the loop and changing it to an AddRange() to add all // of the conflicts in one shot makes it work correctly, thus the change // to the code. // Add all of the conflicts to the list box. ListViewItem[] items = new ListViewItem[warnings.Count]; for (int i = 0; i < warnings.Count; i++) items[i] = new ListViewItem(new String[] { warnings[i].Replacer, warnings[i].File, warnings[i].Source }); listView.Items.AddRange(items); // Load the appropriate prompt text. labelPrompt.Text = StringResources.GetString(type.ToString()); // If we have fatal errors then turn off the continue button, the user // can only cancel. if (fatal) buttonContinue.Enabled = false; }
/// <summary> /// Attempts to resolve tlk file conflicts between the module tlk and any /// tlk's defined in the hifs. It does this by attempting to build a /// new tlk file containing all of the tlk entries from all tlks. If there /// are no overlapping entries in the tlks's then this will succeed and /// the name of the new tlk will be returned, if there are overlaps then /// this will fail and string.Empty will be returned. /// </summary> /// <param name="hakInfos">The HIFs being added to the module</param> /// <param name="module">The module for which we are resolving conflicts</param> /// <param name="moduleInfo">The module info for the module</param> /// <param name="conflicts">The list of files in conflict</param> /// <returns>The name of the merge hak file, or string.Empty if a merge tlk /// could not be generated.</returns> public string ResolveConflicts(HakInfo[] hakInfos, Erf module, ModuleInfo moduleInfo, OverwriteWarningCollection conflicts) { try { // Reset the message shown flag so we show the message once. conflictHakMessageShown = false; // Generate the name of the conflict resolution hak and the directory // in which to place the files that will be added to the hak. conflictHak = GetFileName(module, "hak"); conflictHakDir = NWN.NWNInfo.GetFullFilePath(conflictHak) + ".temp"; OverwriteWarningCollection copy = conflicts.Clone(); foreach (OverwriteWarning conflict in copy) { // Check to see if we can attempt to resolve the conflict, if // we can then attempt to resolve it, and if the resolution is // successful then remove the conflict from the collection. switch (Path.GetExtension(conflict.File).ToLower()) { case ".2da": DisplayConflictHakMessage(module); if (Resolve2daConflict(hakInfos, module, moduleInfo, conflict)) conflicts.Remove(conflict); break; } } // Get all of the files in the conflict hak directory, if there are none // then there is no conflict hak. if (!Directory.Exists(conflictHakDir)) return string.Empty; string[] files = Directory.GetFiles(conflictHakDir); if (0 == files.Length) return string.Empty; // We have some resolved conflicts make the merge hak. Erf hak = Erf.New(Erf.ErfType.HAK, "Auto-generated merge hak"); foreach (string file in files) hak.AddFile(file, true); hak.SaveAs(NWN.NWNInfo.GetFullFilePath(conflictHak)); return conflictHak; } finally { if (Directory.Exists(conflictHakDir)) Directory.Delete(conflictHakDir, true); } }
/// <summary> /// This function checks for hak conflicts, checking to see if any files /// in the hifs will overwrite files in the module or vica versa. If /// overwrites will happen, it prompts the user to see if we should continue, /// throwing an InstallCancelledException() if the user chooses to cancel. /// </summary> /// <param name="hakInfos">The hak infos being added to the module</param> /// <param name="decompressedErfs">The decompressed erfs</param> /// <param name="module">The module</param> /// <param name="moduleInfo">The module info</param> /// <param name="progress">The object implemening the progress interface</param> private void CheckForHakConflicts(HakInfo[] hakInfos, StringCollection decompressedErfs, Erf module, ModuleInfo moduleInfo, IHakInstallProgress progress) { // Create a hashtable for fast lookup and add all of the files in all // of the decompressed erf's to it. Hashtable hifErfHash = new Hashtable(10000); foreach(string directory in decompressedErfs) { // Strip the ".temp" off the end of the name. string erf = Path.GetFileNameWithoutExtension(directory); string[] files = Directory.GetFiles(directory); foreach (string file in files) { // Only add the ERF file if it's not already there. We assume that // the ERF's in the HIF play well together so we ignore duplicates. string key = Path.GetFileName(file).ToLower(); if ("exportinfo.gff" != key && !hifErfHash.Contains(key)) hifErfHash.Add(key, erf.ToLower()); } } // Build a list of all of the added haks. StringCollection hakInfoHaks = new StringCollection(); foreach (HakInfo hakInfo in hakInfos) { StringCollection temp = hakInfo.ModuleProperties["hak"] as StringCollection; if (null != temp) { foreach (string tempString in temp) hakInfoHaks.Add(tempString.ToLower()); } } // Add all of the files in all of the haks to the hash table. Hashtable hifHakHash = new Hashtable(10000); foreach (string hakName in hakInfoHaks) { Erf hak = Erf.Load(NWNInfo.GetFullFilePath(hakName)); StringCollection files = hak.Files; foreach (string file in files) try { string key = file.ToLower(); string hakNameLower = hakName.ToLower(); hifHakHash.Add(key, hakNameLower); } catch (ArgumentException) {} } // At this point we have built a lookup hash table that contains every // file going into the module (either directly in an erf or indirectly // in a hak). Now we need to loop through all of the files in the // module (and all of it's haks) and check to see if any of them are // going to get overwritten. At this point we have several cases. // 1. Module content is going to get replaced by erf content. We // do not handle that case now, we wait until the end and allow // the user to selectivly overwrite whatever they wish. // 2. Module content is going to get replaced by hak content. We must // warn the user that module files will not be used and the module // may not work. // 3. Module hak content is going to get replaced by hak content. Same // as above. // 4. Module hak content is going to overwrite erf content from the hif. // In this case the hif's content is the content that is going to be // ignored, again the user has to be warned. OverwriteWarningCollection hakWarnings = new OverwriteWarningCollection(); OverwriteWarningCollection erfWarnings = new OverwriteWarningCollection(); string moduleFileName = Path.GetFileName(module.FileName); // Loop through all of the files in the module checking to see if files in // added haks will overwrite them. StringCollection moduleFiles = module.Files; foreach (string file in moduleFiles) { string source = hifHakHash[file.ToLower()] as string; if (null != source) hakWarnings.Add(new OverwriteWarning(file.ToLower(), moduleFileName, source)); } // Loop through all of the files in the module's haks checking to see if // files in the added haks will overwrite them or if they will overwrite // files in added erf's. StringCollection moduleHaks = moduleInfo.Haks; foreach (string moduleHak in moduleHaks) { // Check to see if the hak in the module is one of the haks being added (this is // a no-op condition which will result in 100% duplicates, no need to check it). string hak = moduleHak + ".hak"; if (hakInfoHaks.Contains(hak.ToLower())) continue; Erf erf = Erf.Load(NWNInfo.GetFullFilePath(hak)); StringCollection hakFiles = erf.Files; foreach (string file in hakFiles) { // If the file is in the hak hash then it is going to be // overwritten by the hif's haks. string key = file.ToLower(); string source = hifHakHash[key] as string; if (null != source) hakWarnings.Add(new OverwriteWarning(key, Path.GetFileName(erf.FileName.ToLower()), source)); // If the file is in the erf hash then it will overwrite the // hif's erf. source = hifErfHash[key] as string; if (null != source) erfWarnings.Add(new OverwriteWarning(key, source, Path.GetFileName(erf.FileName.ToLower()))); } } // We have built the list of conflicts, before asking the user try to resolve the // conflicts as we may be able to generate a merge hak to resolve some of them. if (hakWarnings.Count > 0) { ConflictResolver resolver = new ConflictResolver(progress); mergeHak = resolver.ResolveConflicts(hakInfos, module, moduleInfo, hakWarnings); } // We have finished checking for files that are going to get overwritten. // If we have any warnings to issue to the user then do so now. if (hakWarnings.Count > 0 && !progress.ShouldOverwrite(hakWarnings, false, OverwriteWarningType.HifsOverwritesModule)) throw new InstallCancelledException(); if (erfWarnings.Count > 0 && !progress.ShouldOverwrite(erfWarnings, false, OverwriteWarningType.ModuleOverwritesHifs)) throw new InstallCancelledException(); }
/// <summary> /// Makes a clone of the collection /// </summary> /// <returns>The clone</returns> public OverwriteWarningCollection Clone() { OverwriteWarningCollection copy = new OverwriteWarningCollection(); foreach (object o in InnerList) copy.InnerList.Add(o); return copy; }
/// <summary> /// This method should ask the user for confirmation of overwriting /// the listed files. If fatal is true then there is no confirmation, /// it is just an informational message that the operation must be aborted. /// </summary> /// <param name="warnings">The list of warnings</param> /// <param name="fatal">True if the warnings are fatal</param> /// <param name="type">The type of overwrite being confirmed</param> /// <returns>True if the operation should proceed</returns> bool IHakInstallProgress.ShouldOverwrite(OverwriteWarningCollection warnings, bool fatal, OverwriteWarningType type) { return true; }
/// <summary> /// This method should ask the user for confirmation of overwriting /// the listed files. If fatal is true then there is no confirmation, /// it is just an informational message that the operation must be aborted. /// </summary> /// <param name="warnings">The list of warnings</param> /// <param name="fatal">True if the warnings are fatal</param> /// <param name="type">The type of overwrite being confirmed</param> /// <returns>True if the operation should proceed</returns> bool IHakInstallProgress.ShouldOverwrite(OverwriteWarningCollection warnings, bool fatal, OverwriteWarningType type) { OverwriteWarningsForm form = new OverwriteWarningsForm(warnings, fatal, type); return DialogResult.OK == form.ShowDialog((Form) this); }