/// <summary>
        /// Extracts an archive into the given folder. (Throws exceptions)
        /// </summary>
        /// <param name="archivePath"></param>
        /// <param name="destinationPath"></param>
        /// <param name="updateProgress"></param>
        public static void ExtractArchive(string archivePath, string destinationPath, Action <Progress> ProgressChanged = null)
        {
            // TODO: Make a ModUtilities.cs?
            string filePath      = Path.GetFullPath(archivePath);
            string fileName      = Path.GetFileName(filePath);
            string fileExtension = Path.GetExtension(filePath);

            Directory.CreateDirectory(destinationPath);

            ProgressChanged?.Invoke(Progress.Indetermined($"Extracting {fileName} ..."));

            /*
             * Depending on file extention:
             */

            // Use Archive2.exe to extract:
            if (fileExtension.ToLower() == ".ba2")
            {
                Archive2.Extract(filePath, destinationPath);
            }

            // Use 7-Zip (7za.exe) to extract:
            else if (Utils.SevenZipSupportedFileTypes.Contains(fileExtension.ToLower()))
            {
                Utils.ExtractArchive(filePath, destinationPath);
            }

            // Not supported:
            else
            {
                throw new NotSupportedException($"File type not supported: {fileExtension}");
            }


            ProgressChanged?.Invoke(Progress.Done("Extracting finished."));
        }
Пример #2
0
        /// <summary>
        /// Loads and converts legacy managed mods to the new format.
        /// It adds them to an already existing ManagedMods object.
        /// </summary>
        public static void ConvertLegacy(ManagedMods mods, GameEdition edition, Action <Progress> ProgressChanged = null)
        {
            Directory.CreateDirectory(Path.Combine(mods.GamePath, "FrozenData"));

            XDocument xmlDoc = XDocument.Load(Path.Combine(mods.ModsPath, "manifest.xml"));

            // I added a doNotImport="true" attribute, so I can check, whether the manifest.xml has only been generated for backwards-compatibility.
            // If it exists, we can just skip the import:
            if (xmlDoc.Root.Attribute("doNotImport") != null)
            {
                ProgressChanged?.Invoke(Progress.Aborted("Import skipped."));
                return;
            }

            // Make backups:
            File.Copy(Path.Combine(mods.ModsPath, "manifest.xml"), Path.Combine(mods.ModsPath, "manifest.old.xml"), true);
            if (File.Exists(Path.Combine(mods.ModsPath, "managed.xml")))
            {
                File.Copy(Path.Combine(mods.ModsPath, "managed.xml"), Path.Combine(mods.ModsPath, "managed.old.xml"), true);
            }

            // Converting the legacy list will completely erase the current mod list:
            mods.Mods.Clear();

            /*
             * Converting:
             */
            int modCount = xmlDoc.Descendants("Mod").Count();
            int modIndex = 0;

            foreach (XElement xmlMod in xmlDoc.Descendants("Mod"))
            {
                modIndex++;

                if (xmlMod.Attribute("modFolder") == null)
                {
                    continue;
                }

                ManagedMod mod = new ManagedMod(mods.GamePath);

                string managedFolderName = xmlMod.Attribute("modFolder").Value;
                string managedFolderPath = Path.Combine(mods.ModsPath, managedFolderName);
                string frozenArchivePath = Path.Combine(mods.ModsPath, managedFolderName, "frozen.ba2");
                bool   isFrozen          = File.Exists(frozenArchivePath);

                mod.ManagedFolderName = managedFolderName;

                if (xmlMod.Attribute("title") != null)
                {
                    mod.Title = xmlMod.Attribute("title").Value;
                }

                string progressTitle      = $"Converting \"{mod.Title}\" ({modIndex} of {modCount})";
                float  progressPercentage = (float)modIndex / (float)modCount;

                // In case the mod was "frozen" before,
                // we'll need to move the *.ba2 archive into the FrozenData folder and then extract it.
                if (isFrozen)
                {
                    ProgressChanged?.Invoke(Progress.Ongoing($"{progressTitle}: Extracting *.ba2 archive...", progressPercentage));
                    File.Move(frozenArchivePath, mod.FrozenArchivePath);
                    Archive2.Extract(mod.FrozenArchivePath, managedFolderPath);
                    mod.Frozen = true;
                    mod.Freeze = true;
                }

                // OBSOLETE: We need to rename the old folder to fit with the new format.

                /*if (Directory.Exists(managedFolderPath))
                 * {
                 *  ProgressChanged?.Invoke(Progress.Ongoing($"{progressTitle}: Moving managed folder...", progressPercentage));
                 *  if (Directory.Exists(mod.ManagedFolderPath))
                 *      Directory.Delete(mod.ManagedFolderPath, true);
                 *  Directory.Move(managedFolderPath, mod.ManagedFolderPath);
                 * }*/

                ProgressChanged?.Invoke(Progress.Ongoing($"{progressTitle}: Parsing XML...", progressPercentage));

                if (xmlMod.Attribute("url") != null)
                {
                    mod.URL = xmlMod.Attribute("url").Value;
                }

                if (xmlMod.Attribute("version") != null)
                {
                    mod.Version = xmlMod.Attribute("version").Value;
                }

                if (xmlMod.Attribute("enabled") != null)
                {
                    try
                    {
                        mod.Deployed = XmlConvert.ToBoolean(xmlMod.Attribute("enabled").Value);
                    }
                    catch
                    {
                        mod.Deployed = false;
                    }
                    mod.Enabled = mod.Deployed;
                }

                if (xmlMod.Attribute("installType") != null)
                {
                    switch (xmlMod.Attribute("installType").Value)
                    {
                    case "Loose":
                        mod.PreviousMethod = ManagedMod.DeploymentMethod.LooseFiles;
                        break;

                    case "SeparateBA2":
                        mod.PreviousMethod = ManagedMod.DeploymentMethod.SeparateBA2;
                        break;

                    case "BA2Archive":         // Backward compatibility
                    case "BundledBA2":
                    case "BundledBA2Textures": // Backward compatibility
                    default:
                        mod.PreviousMethod = ManagedMod.DeploymentMethod.BundledBA2;
                        break;
                    }
                    mod.Method = mod.PreviousMethod;
                }

                if (xmlMod.Attribute("format") != null)
                {
                    switch (xmlMod.Attribute("format").Value)
                    {
                    case "General":
                        mod.CurrentFormat = ManagedMod.ArchiveFormat.General;
                        break;

                    case "DDS":     // Backward compatibility
                    case "Textures":
                        mod.CurrentFormat = ManagedMod.ArchiveFormat.Textures;
                        break;

                    case "Auto":
                    default:
                        mod.CurrentFormat = ManagedMod.ArchiveFormat.Auto;
                        break;
                    }
                    mod.Format = mod.CurrentFormat;
                }

                if (xmlMod.Attribute("compression") != null)
                {
                    switch (xmlMod.Attribute("compression").Value)
                    {
                    case "Default":     // Backward compatibility
                    case "Compressed":
                        mod.CurrentCompression = ManagedMod.ArchiveCompression.Compressed;
                        break;

                    case "None":     // Backward compatibility
                    case "Uncompressed":
                        mod.CurrentCompression = ManagedMod.ArchiveCompression.Uncompressed;
                        break;

                    case "Auto":
                    default:
                        mod.CurrentCompression = ManagedMod.ArchiveCompression.Auto;
                        break;
                    }
                    mod.Compression = mod.CurrentCompression;
                }

                if (xmlMod.Attribute("archiveName") != null)
                {
                    mod.CurrentArchiveName = xmlMod.Attribute("archiveName").Value;
                    mod.ArchiveName        = mod.CurrentArchiveName;
                }

                if (xmlMod.Attribute("root") != null)
                {
                    mod.CurrentRootFolder = xmlMod.Attribute("root").Value;
                    mod.RootFolder        = mod.CurrentRootFolder;
                    foreach (XElement xmlFile in xmlMod.Descendants("File"))
                    {
                        if (xmlFile.Attribute("path") != null)
                        {
                            mod.LooseFiles.Add(xmlFile.Attribute("path").Value);
                        }
                    }
                }

                /*if (xmlMod.Attribute("frozen") != null)
                 * {
                 *  frozen = XmlConvert.ToBoolean(xmlMod.Attribute("frozen").Value);
                 * }*/

                mods.Add(mod);
            }

            // Legacy resource list:
            if (IniFiles.Config.GetBool("Preferences", "bMultipleGameEditionsUsed", false))
            {
                string backedUpList = IniFiles.Config.GetString("Mods", $"sResourceIndexFileList{edition}", "");
                string actualList   = IniFiles.F76Custom.GetString("Archive", "sResourceIndexFileList", "");
                if (backedUpList != "")
                {
                    mods.Resources.ReplaceRange(ResourceList.FromString(backedUpList));
                }
                else if (actualList != "")
                {
                    mods.Resources.ReplaceRange(ResourceList.FromString(actualList));
                }
            }

            ProgressChanged?.Invoke(Progress.Ongoing("Saving XML...", 1f));
            mods.Save();

            ProgressChanged?.Invoke(Progress.Done("Legacy mods imported."));
        }