/// <summary> /// This function checks for tlk conflicts, checking to see if the module /// and hifs have tlk files. If there are multiple tlk files it will attempt /// to generate a merge tlk file, if this cannot be done it will display an /// error message and throw an InstallCancelledException to cancel the install. /// </summary> /// <param name="hakInfos">The hak infos being added to the module</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 CheckForTlkConflicts(HakInfo[] hakInfos, Erf module, ModuleInfo moduleInfo, IHakInstallProgress progress) { // Create a tlk string collection and add the module's tlk if it has one. StringCollection tlks = new StringCollection(); if (string.Empty != moduleInfo.CustomTlk) tlks.Add(moduleInfo.CustomTlk.ToLower() + ".tlk"); // Add all of the tlk's from all of the HIFs. foreach (HakInfo hif in hakInfos) { StringCollection hifTlks = hif.ModuleProperties["customtlk"]; if (null != hifTlks && hifTlks.Count > 0) { // Loop through the tlk's individually to exclude duplicates. foreach (string hifTlk in hifTlks) { string lower = hifTlk.ToLower(); if (!tlks.Contains(lower)) tlks.Add(lower); } } } // If we have less than 2 tlks there is no conflict to resolve. if (tlks.Count < 2) return; // We have 2 or more tlk files, create a conflict resolver to // build a merge tlk file. ConflictResolver resolver = new ConflictResolver(progress); string[] tlkStrings = new string[tlks.Count]; tlks.CopyTo(tlkStrings, 0); mergeTlk = resolver.ResolveTlkConflict(module, tlkStrings); // If we don't get a merge tlk back from the conflict resolver then we couldn't // resolve the conflict. This is a fatal error so display an error message and // cancel the install. if (string.Empty == mergeTlk) { progress.DisplayErrorMessage("The module and custom content contain tlk files " + "that cannot be merged. The module update will be aborted."); throw new InstallCancelledException(); } // Save the merge tlk as the module's custom tlk. moduleInfo.CustomTlk = Path.GetFileNameWithoutExtension(mergeTlk.ToLower()); }
/// <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(); }