Ejemplo n.º 1
0
        /// <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();
        }