public static void Freeze(ManagedMod mod)
        {
            // TODO: Remove connection to ManagedMods
            // Only freeze if not already frozen:
            if (mod.Frozen && File.Exists(mod.FrozenArchivePath))
            {
                // TODO: ModActions.Freeze: Should the mod get "refrozen"?
                //ManagedMods.Instance.logFile.WriteLine($"Cannot freeze a mod ('{mod.Title}') that is already frozen.\n");
                return;
            }

            Directory.CreateDirectory(mod.FrozenDataPath);

            // Getting preset:
            Archive2.Preset preset = ModHelpers.GetArchive2Preset(mod);

            ModDeployment.LogFile.WriteLine($"      Freezing mod '{mod.Title}'...");
            ModDeployment.LogFile.WriteLine($"         Format:      {preset.format}");
            ModDeployment.LogFile.WriteLine($"         Compression: {preset.compression}");
            ModDeployment.LogFile.WriteLine($"         Destination: FrozenData\\{mod.FrozenArchiveName}");

            // Create archive:
            Archive2.Create(mod.FrozenArchivePath, mod.ManagedFolderPath, preset);

            // Change DiskState and save:
            mod.Frozen            = true;
            mod.FrozenCompression = mod.Compression;
            mod.FrozenFormat      = mod.Format;
        }
Example #2
0
        public static void Create(String ba2Archive, String folder, Archive2.Compression compression, Archive2.Format format)
        {
            if (!Directory.Exists(folder))
            {
                return;
            }

            String compressionStr = Enum.GetName(typeof(Archive2.Compression), (int)compression);
            String formatStr      = Enum.GetName(typeof(Archive2.Format), (int)format);

            folder = Path.GetFullPath(folder);
            Archive2.Call($"\"{folder}\" -create=\"{ba2Archive}\" -compression={compressionStr} -format={formatStr} -root=\"{folder}\" -tempFiles -quiet");
        }
Example #3
0
        /// <summary>
        /// Used in the deployment chain to pack each bundled temporary folder to an archive.
        /// </summary>
        private static void PackBundledArchives(ResourceList resources, DeployArchiveList archives, bool freezeArchives)
        {
            // For each archive...
            foreach (DeployArchive archive in archives.Reverse())
            {
                // ... if needed ...
                if (archive.Count > 0 && !Utils.IsDirectoryEmpty(archive.TempPath))
                {
                    // ... pack the temporary folder to an archive ...
                    if (freezeArchives)
                    {
                        LogFile.WriteLine($"      Freezing archive '{archive.ArchiveName}'");

                        // either freeze to FrozenData and then copy to Data:
                        Archive2.Create(archive.GetFrozenArchivePath(), archive.TempPath, archive.Compression, archive.Format);

                        if (Configuration.bUseHardlinks)
                        {
                            Utils.CreateHardLink(archive.GetFrozenArchivePath(), archive.GetArchivePath(), true);
                        }
                        else
                        {
                            File.Copy(archive.GetFrozenArchivePath(), archive.GetArchivePath(), true);
                        }
                    }
                    else
                    {
                        LogFile.WriteLine($"      Creating archive '{archive.ArchiveName}'");

                        // or create directly in Data:
                        Archive2.Create(archive.GetArchivePath(), archive.TempPath, archive.Compression, archive.Format);
                    }

                    // ... and add it to the resource list.
                    resources.Insert(0, archive.ArchiveName);
                }
            }

            // Clean up after we're finished.
            LogFile.WriteLine($"      Deleting temporary folder...");
            archives.DeleteTempFolder();
        }
        /// <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."));
        }
Example #5
0
        /// <summary>
        /// Used in the deployment chain to deploy a single mod with the SeparateBA2 method.
        /// Freezes a mod if necessary.
        /// </summary>
        private static void DeploySeparateArchive(ManagedMod mod, ResourceList resources)
        {
            LogFile.WriteLine($"   Installing mod '{mod.Title}' as SeparateBA2");

            // If mod is supposed to be deployed frozen...
            if (mod.Freeze)
            {
                // ... freeze if necessary ...
                if (!mod.Frozen)
                {
                    //LogFile.WriteLine($"      Freezing mod...");
                    ModActions.Freeze(mod);
                }

                LogFile.WriteLine($"      Copying frozen archive...");

                // ... and copy it to the Data folder.
                if (Configuration.bUseHardlinks)
                {
                    Utils.CreateHardLink(
                        mod.FrozenArchivePath,
                        mod.ArchivePath,
                        true);
                }
                else
                {
                    File.Copy(
                        mod.FrozenArchivePath,
                        mod.ArchivePath,
                        true);
                }
            }

            // If mod isn't supposed to be deployed frozen...
            else
            {
                // ... unfreeze mod if needed ...
                if (mod.Frozen)
                {
                    LogFile.WriteLine($"      Unfreezing mod...");
                    ModActions.Unfreeze(mod);
                }

                // Getting preset:
                Archive2.Preset preset = ModHelpers.GetArchive2Preset(mod);

                LogFile.WriteLine($"      Creating new archive...");
                LogFile.WriteLine($"         Format:      {preset.format}");
                LogFile.WriteLine($"         Compression: {preset.compression}");

                // ... and create a new archive.
                Archive2.Create(
                    mod.ArchivePath,
                    mod.ManagedFolderPath,
                    preset);
            }

            // Finally, update the disk state ...
            mod.CurrentArchiveName = mod.ArchiveName;
            mod.CurrentCompression = mod.Frozen ? mod.FrozenCompression : mod.Compression;
            mod.CurrentFormat      = mod.Frozen ? mod.FrozenFormat : mod.Format;
            mod.Deployed           = true;
            mod.PreviousMethod     = ManagedMod.DeploymentMethod.SeparateBA2;

            // ... and add the archive to the resource list.
            resources.Add(mod.ArchiveName);

            LogFile.WriteLine($"      Installed.");
        }
Example #6
0
 public static void Create(String ba2Archive, String folder, Archive2.Preset preset)
 {
     Archive2.Create(ba2Archive, folder, preset.compression, preset.format);
 }
Example #7
0
 public static void Create(String ba2Archive, String folder)
 {
     Archive2.Create(ba2Archive, folder, Archive2.Compression.Default, Archive2.Format.General);
 }
Example #8
0
 public static void Explore()
 {
     Archive2.CallParallel("");
 }
Example #9
0
 public static void Explore(String ba2Archive)
 {
     Archive2.CallParallel($"\"{ba2Archive}\"");
 }
Example #10
0
 public static void Extract(String ba2Archive, String outputFolder)
 {
     Archive2.Call($"\"{ba2Archive}\" -extract=\"{outputFolder}\" -quiet");
 }
Example #11
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."));
        }