Ejemplo n.º 1
0
        public static void RemoveAll(ManagedMods mods)
        {
            LogFile.WriteLine("Removing all installed mods");

            // Delete bundled archives:
            DeployArchiveList deployArchives = new DeployArchiveList(mods.GamePath);

            foreach (DeployArchive deployArchive in deployArchives)
            {
                LogFile.WriteLine($"   Removing {deployArchive.ArchiveName}");
                if (File.Exists(deployArchive.GetArchivePath()))
                {
                    File.Delete(deployArchive.GetArchivePath());
                }
                mods.Resources.Remove(deployArchive.ArchiveName);
            }
            LogFile.WriteLine($"   Deleting temporary folders");
            deployArchives.DeleteTempFolder();

            // Remove mods:
            foreach (ManagedMod mod in mods)
            {
                LogFile.WriteLine($"   Removing mod {mod.Title}");
                ModDeployment.Remove(mod, mods.Resources, mods.GamePath);
            }

            mods.Save();
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Deletes all files of the mod and removes it from the list.
 /// Saves the xml file afterwards.
 /// </summary>
 public static void DeleteMod(ManagedMods mods, int index, Action <Progress> ProgressChanged = null)
 {
     ModActions.DeleteFiles(mods[index]);
     mods.RemoveAt(index);
     mods.Save();
     ProgressChanged?.Invoke(Progress.Done("Mod deleted."));
 }
        /// <summary>
        /// Extracts the archive and adds the mod to the list.
        /// Saves the xml file afterwards.
        /// </summary>
        /// <param name="useSourceBA2Archive">When false, creates a new "frozen" mod.</param>
        public static void InstallArchive(ManagedMods mods, string filePath, bool useSourceBA2Archive = false, Action <Progress> ProgressChanged = null)
        {
            ManagedMod newMod = ModInstallations.FromArchive(mods.GamePath, filePath, useSourceBA2Archive, ProgressChanged);

            mods.Add(newMod);
            mods.Save();
            ProgressChanged?.Invoke(Progress.Done("Mod archive installed."));
        }
        /// <summary>
        /// Copies the folder and adds the mod to the list.
        /// Saves the xml file afterwards.
        /// </summary>
        public static void InstallFolder(ManagedMods mods, string folderPath, Action <Progress> ProgressChanged = null)
        {
            ManagedMod newMod = ModInstallations.FromFolder(mods.GamePath, folderPath, ProgressChanged);

            mods.Add(newMod);
            mods.Save();
            ProgressChanged?.Invoke(Progress.Done("Mod folder installed."));
        }
 /// <summary>
 /// Freezes the mods.
 /// </summary>
 public static void Freeze(ManagedMods mods, IEnumerable <int> indices)
 {
     foreach (int index in indices)
     {
         ModActions.Freeze(mods[index]);
     }
     mods.Save();
 }
        /// <summary>
        /// Adds a new blank mod.
        /// </summary>
        public static void InstallBlank(ManagedMods mods)
        {
            ManagedMod newMod = new ManagedMod(mods.GamePath);

            newMod.Title       = "Untitled";
            newMod.ArchiveName = "untitled.ba2";
            Directory.CreateDirectory(newMod.ManagedFolderPath);
            mods.Add(newMod);
            mods.Save();
        }
        /// <summary>
        /// Unfreezes the mods.
        /// </summary>
        public static void Unfreeze(ManagedMods mods, IEnumerable <int> indices, Action <Progress> ProgressChanged = null)
        {
            int count = indices.Count();
            int n     = 1;

            foreach (int index in indices)
            {
                ModActions.Unfreeze(mods[index]);
                ProgressChanged?.Invoke(Progress.Ongoing($"Unfreezing {n} of {count} mod(s)...", (float)n++ / (float)count));
            }
            mods.Save();
            ProgressChanged?.Invoke(Progress.Done($"{count} mod(s) thawed."));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Deletes multiple mods and removes them from the list.
        /// Saves the xml file afterwards.
        /// </summary>
        public static void DeleteMods(ManagedMods mods, List <int> indices, Action <Progress> ProgressChanged = null)
        {
            indices = indices.OrderByDescending(i => i).ToList();
            int fi    = 0;
            int count = indices.Count();

            foreach (int index in indices)
            {
                ProgressChanged?.Invoke(Progress.Ongoing($"Deleting mod {++fi} of {count}.", (float)(fi - 1) / (float)count));
                ModActions.DeleteFiles(mods[index]);
                mods.RemoveAt(index);
                mods.Save();
            }
            ProgressChanged?.Invoke(Progress.Done($"{count} mods deleted."));
        }
        /// <summary>
        /// Downloads and installs a mod from NexusMods. (by using NXM links)
        /// </summary>
        /// <param name="useSourceBA2Archive">When false, creates a new "frozen" mod.</param>
        public static bool InstallRemote(ManagedMods mods, string nxmLinkStr, bool useSourceBA2Archive = false, Action <Progress> ProgressChanged = null)
        {
            NXMLink nxmLink = NXMHandler.ParseLink(nxmLinkStr);

            // Get the download link from NexusMods:
            ProgressChanged(Progress.Indetermined("Requesting mod download link..."));
            string dlLinkStr = NMMod.RequestDownloadLink(nxmLink);

            if (dlLinkStr == null)
            {
                ProgressChanged?.Invoke(Progress.Aborted("Couldn't retrieve download link..."));
                return(false);
            }
            Uri    dlLink     = new Uri(dlLinkStr);
            string dlFileName = dlLink.Segments.Last();
            string dlPath     = Path.Combine(Shared.DownloadsFolder, dlFileName);

            // Download mod, unless we already have it:
            if (!File.Exists(dlPath))
            {
                DownloadFile(dlLink.OriginalString, dlPath, ProgressChanged);
            }

            if (!File.Exists(dlPath))
            {
                ProgressChanged?.Invoke(Progress.Aborted("Download failed."));
                return(false);
            }

            // Get remote mod info:
            ProgressChanged(Progress.Indetermined("Requesting mod information and thumbnail..."));
            NMMod nmMod = NexusMods.RequestModInformation(nxmLink.modId);

            // Install mod:
            ProgressChanged(Progress.Indetermined($"Installing '{nmMod.Title}'..."));
            ManagedMod newMod = ModInstallations.FromArchive(mods.GamePath, dlPath, useSourceBA2Archive, ProgressChanged);

            newMod.Title   = nmMod.Title;
            newMod.Version = nmMod.LatestVersion;
            newMod.URL     = nmMod.URL;
            mods.Add(newMod);
            mods.Save();
            ProgressChanged?.Invoke(Progress.Done($"'{nmMod.Title}' installed."));

            return(true);
        }
Ejemplo n.º 10
0
        public static void Deploy(ManagedMods mods, Action <Progress> ProgressChanged, bool invalidateBundledFrozenArchives = true)
        {
            LogFile.WriteLine("\n\n");
            LogFile.WriteTimeStamp();
            LogFile.WriteLine($"Version {Shared.VERSION}, deploying...");
            LogFile.WriteLine($"Game path: {mods.GamePath}");

            // TODO: More descriptive ProgressChanged
            ProgressChanged?.Invoke(Progress.Indetermined("Deploying..."));

            // Check for conflicts:
            LogFile.WriteLine("Checking for conflicting archive names...");
            List <ModHelpers.Conflict> conflicts = ModHelpers.GetConflictingArchiveNames(mods.Mods);

            if (conflicts.Count > 0)
            {
                LogFile.WriteLine("Conflicts found, abort.");
                foreach (ModHelpers.Conflict conflict in conflicts)
                {
                    LogFile.WriteLine($"   Conflict: {conflict.conflictText}");
                }
                throw new DeploymentFailedException("Conflicting archive names.");
            }

            // Restore *.dll files:
            RestoreAddedDLLs(mods.GamePath);

            // Remove all currently deployed mods:
            ProgressChanged?.Invoke(Progress.Indetermined("Removing mods..."));
            ModDeployment.RemoveAll(mods);
            mods.Save();

            // If mods are enabled:
            if (!mods.ModsDisabled)
            {
                LogFile.WriteLine("Installing mods...");

                // Deploy all SeparateBA2 and Loose mods:
                foreach (ManagedMod mod in mods)
                {
                    ProgressChanged?.Invoke(Progress.Indetermined($"Deploying {mod.Title}..."));
                    if (mod.Enabled &&
                        Directory.Exists(mod.ManagedFolderPath) &&
                        !Utils.IsDirectoryEmpty(mod.ManagedFolderPath))
                    {
                        switch (mod.Method)
                        {
                        case ManagedMod.DeploymentMethod.SeparateBA2:
                            DeploySeparateArchive(mod, mods.Resources);
                            mods.Save();
                            break;

                        case ManagedMod.DeploymentMethod.LooseFiles:
                            DeployLooseFiles(mods, mod, mods.GamePath);
                            mods.Save();
                            break;
                        }
                    }
                }

                // Deploy all BundledBA2 mods:
                ProgressChanged?.Invoke(Progress.Indetermined($"Building bundled archives..."));
                ModDeployment.DeployBundledArchives(mods, IniFiles.Config.GetBool("Mods", "bFreezeBundledArchives", false), invalidateBundledFrozenArchives);

                mods.Save();
                ProgressChanged?.Invoke(Progress.Done("Mods deployed."));
            }
            else
            {
                ProgressChanged?.Invoke(Progress.Done("Mods removed."));
            }

            LogFile.WriteLine("Deployment finished.");
            LogFile.WriteLine($"Resource list ({mods.Resources.Count} files): \"{mods.Resources}\"");
        }
        /// <summary>
        /// Looks through the resource lists in the *.ini and imports *.ba2 archives.
        /// </summary>
        public static void ImportInstalledMods(ManagedMods mods, Action <Progress> ProgressChanged = null)
        {
            // TODO: ProgressChanged for ImportInstalledMods
            ProgressChanged?.Invoke(Progress.Indetermined("Importing already installed mods..."));

            // Get all archives:
            ResourceList IndexFileList = ResourceList.GetResourceIndexFileList();
            ResourceList Archive2List  = ResourceList.GetResourceArchive2List();

            /*
             * Prepare list:
             */

            // Add all archives:
            List <string> installedMods = new List <string>();

            installedMods.AddRange(IndexFileList);
            installedMods.AddRange(Archive2List);
            installedMods.AddRange(mods.Resources);

            // Remove bundled archives:
            installedMods = installedMods.FindAll(e => !e.ToLower().Contains("bundled"));

            // Remove currently managed archives:
            foreach (ManagedMod mod in mods)
            {
                if (mod.PreviousMethod == ManagedMod.DeploymentMethod.SeparateBA2)
                {
                    installedMods.Remove(mod.CurrentArchiveName);
                }
            }

            // Ignore any game files ("SeventySix - *.ba2"):
            foreach (string archiveName in IndexFileList)
            {
                if (archiveName.Trim().ToLower().StartsWith("seventysix"))
                {
                    installedMods.Remove(archiveName);
                }
            }
            foreach (string archiveName in Archive2List)
            {
                if (archiveName.Trim().ToLower().StartsWith("seventysix"))
                {
                    installedMods.Remove(archiveName);
                }
            }
            foreach (string archiveName in mods.Resources)
            {
                if (archiveName.Trim().ToLower().StartsWith("seventysix"))
                {
                    installedMods.Remove(archiveName);
                }
            }

            /*
             * Import installed mods:
             */

            foreach (string archiveName in installedMods)
            {
                string path = Path.Combine(mods.GamePath, "Data", archiveName);
                if (File.Exists(path) && !archiveName.Trim().ToLower().StartsWith("seventysix"))
                {
                    // Import archive:
                    ModInstallations.InstallArchive(mods, path, true);
                    File.Delete(path);

                    // Remove from lists:
                    IndexFileList.Remove(archiveName);
                    Archive2List.Remove(archiveName);
                }
            }

            // Save *.ini files:
            IndexFileList.CommitToINI();
            Archive2List.CommitToINI();
            //IniFiles.Instance.SaveAll();

            mods.Save();
        }
 /// <summary>
 /// Freezes the mod.
 /// </summary>
 public static void Freeze(ManagedMods mods, int index)
 {
     ModActions.Freeze(mods[index]);
     mods.Save();
 }
 /// <summary>
 /// Unfreezes the mod.
 /// </summary>
 public static void Unfreeze(ManagedMods mods, int index, Action <Progress> ProgressChanged = null)
 {
     ModActions.Unfreeze(mods[index]);
     mods.Save();
     ProgressChanged?.Invoke(Progress.Done("Mod thawed."));
 }
Ejemplo n.º 14
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."));
        }