public static void CleanUpFolder(string folderPath, Action <Progress> ProgressChanged = null) { ProgressChanged?.Invoke(Progress.Indetermined("Cleaning up mod folder.")); foreach (string subFolderPath in Directory.EnumerateDirectories(folderPath)) { string subFolderName = Path.GetFileName(subFolderPath).ToLower(); // Move data folder one up: if (subFolderName == "data") { ModInstallations.MoveDirectory(subFolderPath, folderPath); } } foreach (String filePath in Directory.EnumerateFiles(folderPath)) { string fileExtension = Path.GetExtension(filePath).ToLower().Trim(); // Extract archives within folder: if (fileExtension == ".ba2" || Utils.SevenZipSupportedFileTypes.Contains(fileExtension)) { ModInstallations.ExtractArchive(filePath, folderPath, ProgressChanged); File.Delete(filePath); } // Delete crap: else if (fileExtension == ".txt") { File.Delete(filePath); } } }
/// <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> /// 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); }
/// <summary> /// Creates a new mod from any supported archive. (zip, tar, rar, 7z, ba2) /// BA2 files can be installed frozen if needed. /// </summary> /// <param name="gamePath">Path to the game installation</param> /// <param name="filePath">Path to archive</param> /// <param name="useSourceBA2Archive">When false, creates a new "frozen" mod.</param> /// <returns></returns> private static ManagedMod FromArchive(string gamePath, string filePath, bool useSourceBA2Archive = false, Action <Progress> ProgressChanged = null) { // Get path information: string longFilePath = EnsureLongPathSupport(filePath); string fileNameWOEx = Path.GetFileNameWithoutExtension(longFilePath); string fileExtension = Path.GetExtension(longFilePath); // Install mod: ManagedMod newMod = new ManagedMod(gamePath); newMod.Title = fileNameWOEx; newMod.ArchiveName = fileNameWOEx + ".ba2"; newMod.ManagedFolderName = fileNameWOEx; if (!Utils.IsFileNameValid(newMod.ManagedFolderName) || Directory.Exists(newMod.ManagedFolderPath)) { newMod.ManagedFolderName = newMod.DefaultManagedFolderName; } // Extract mod: ProgressChanged?.Invoke(Progress.Indetermined($"Extracting {Path.GetFileName(filePath)}")); ModInstallations.ExtractArchive(longFilePath, newMod.ManagedFolderPath); // Freeze mod conditionally: if (useSourceBA2Archive && fileExtension == ".ba2") { // Copy *.ba2 into FrozenData: FileInfo frozenPath = new FileInfo(newMod.FrozenArchivePath); ProgressChanged?.Invoke(Progress.Indetermined($"Copying {Path.GetFileName(filePath)} to {frozenPath.DirectoryName}")); Directory.CreateDirectory(frozenPath.DirectoryName); File.Copy(longFilePath, frozenPath.FullName, true); newMod.Frozen = true; newMod.Freeze = true; newMod.PreviousMethod = ManagedMod.DeploymentMethod.SeparateBA2; newMod.Method = ManagedMod.DeploymentMethod.SeparateBA2; } else { ModActions.CleanUpFolder(newMod.ManagedFolderPath, ProgressChanged); ModActions.DetectOptimalModInstallationOptions(newMod); } return(newMod); }
/// <summary> /// Extracts the archive and then copy and replaces from the temp folder into the managed mod folder. /// </summary> public static void AddArchive(ManagedMod mod, string filePath, Action <Progress> ProgressChanged = null) { string longFilePath = EnsureLongPathSupport(filePath); string tempFolderPath = Path.Combine(Path.GetTempPath(), $"tmp_{mod.guid}"); if (Directory.Exists(tempFolderPath)) { Directory.Delete(tempFolderPath, true); } Directory.CreateDirectory(tempFolderPath); ProgressChanged?.Invoke(Progress.Indetermined($"Extracting {Path.GetFileName(filePath)}")); ModInstallations.ExtractArchive(longFilePath, tempFolderPath); ModActions.CleanUpFolder(tempFolderPath, ProgressChanged); CopyDirectory(tempFolderPath, mod.ManagedFolderPath, ProgressChanged); Directory.Delete(tempFolderPath, true); ProgressChanged?.Invoke(Progress.Done("Archive added to mod.")); }
/// <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(); }