/// <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> /// Loads the information about this nxmlink into this object. Subscribe to OnInitialized() to know when it has initialized and is ready for download to begin. /// THIS IS A BLOCKING CALL DO NOT RUN ON THE UI /// </summary> public void Initialize() { Log.Information($@"Initializing {NXMLink}"); Task.Run(() => { try { DownloadLinks.Clear(); var nxmlink = NXMLink.Substring(6); var queryPos = nxmlink.IndexOf('?'); var info = queryPos > 0 ? nxmlink.Substring(0, queryPos) : nxmlink; var infos = info.Split('/'); domain = infos[0]; var modid = int.Parse(infos[2]); var fileid = int.Parse(infos[4]); if (!NexusModsUtilities.AllSupportedNexusDomains.Contains(domain)) { Log.Error($@"Cannot download file from unsupported domain: {domain}. Open your preferred mod manager from that game first"); Initialized = true; ProgressIndeterminate = false; OnModDownloadError?.Invoke(this, M3L.GetString(M3L.string_interp_dialog_modNotForThisModManager, domain)); return; } ModFile = NexusModsUtilities.GetClient().ModFiles.GetModFile(domain, modid, fileid).Result; if (ModFile != null) { if (ModFile.Category != FileCategory.Deleted) { if (queryPos > 0) { // download with manager string querystring = nxmlink.Substring(queryPos); var parameters = HttpUtility.ParseQueryString(querystring); // Check if parameters are correct! DownloadLinks.AddRange(NexusModsUtilities.GetDownloadLinkForFile(domain, modid, fileid, parameters[@"key"], int.Parse(parameters[@"expires"])).Result); } else { // premium? if (!NexusModsUtilities.UserInfo.IsPremium) { Log.Error( $@"Cannot download {ModFile.FileName}: User is not premium, but this link is not generated from NexusMods"); Initialized = true; ProgressIndeterminate = false; OnModDownloadError?.Invoke(this, M3L.GetString(M3L.string_dialog_mustBePremiumUserToDownload)); return; } DownloadLinks.AddRange(NexusModsUtilities.GetDownloadLinkForFile(domain, modid, fileid) ?.Result); } ProgressMaximum = ModFile.Size * 1024; // Bytes Initialized = true; Log.Error($@"ModDownload has initialized: {ModFile.FileName}"); OnInitialized?.Invoke(this, null); } else { Log.Error($@"Cannot download {ModFile.FileName}: File deleted from NexusMods"); Initialized = true; ProgressIndeterminate = false; OnModDownloadError?.Invoke(this, M3L.GetString(M3L.string_dialog_cannotDownloadDeletedFile)); } } } catch (Exception e) { Log.Error($@"Error downloading {ModFile?.FileName}: {e.Message}"); Initialized = true; ProgressIndeterminate = false; OnModDownloadError?.Invoke(this, M3L.GetString(M3L.string_interp_errorDownloadingModX, e.Message)); } }); }