public static NexusProtocolLink Parse(string link) { if (!link.StartsWith(@"nxm://")) { return(null); // not an nxm link! } var npl = new NexusProtocolLink() { Link = link }; var nxmlink = link.Substring(6); // remove 'nxm://' var queryPos = nxmlink.IndexOf('?'); var info = queryPos > 0 ? nxmlink.Substring(0, queryPos) : nxmlink; var infos = info.Split('/'); npl.Domain = infos[0]; npl.ModId = int.Parse(infos[2]); npl.FileId = int.Parse(infos[4]); if (queryPos > 0) { var parameters = HttpUtility.ParseQueryString(nxmlink.Substring(queryPos)); if (int.TryParse(parameters[@"expires"], out var exp)) { npl.KeyExpiry = exp; npl.Key = parameters[@"key"]; } } return(npl); }
/// <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(); ProtocolLink = NexusProtocolLink.Parse(NXMLink); if (ProtocolLink == null) { return; // Parse failed. } if (!NexusModsUtilities.AllSupportedNexusDomains.Contains(ProtocolLink?.Domain)) { Log.Error($@"Cannot download file from unsupported domain: {ProtocolLink?.Domain}. Open your preferred mod manager from that game first"); Initialized = true; ProgressIndeterminate = false; OnModDownloadError?.Invoke(this, M3L.GetString(M3L.string_interp_dialog_modNotForThisModManager, ProtocolLink.Domain)); return; } ModFile = NexusModsUtilities.GetClient().ModFiles.GetModFile(ProtocolLink.Domain, ProtocolLink.ModId, ProtocolLink.FileId).Result; if (ModFile != null) { if (ModFile.Category != FileCategory.Deleted) { if (ProtocolLink.Key != null) { // Website click if (ProtocolLink.Domain is @"masseffect" or @"masseffect2" && !IsDownloadWhitelisted(ProtocolLink.Domain, ModFile)) { // Check to see file has moddesc.ini the listing var fileListing = NexusModsUtilities.GetFileListing(ModFile); if (fileListing == null || !HasModdescIni(fileListing)) { Log.Error($@"This file is not whitelisted for download and does not contain a moddesc.ini file, this is not a mod manager mod: {ModFile.FileName}"); Initialized = true; ProgressIndeterminate = false; OnModDownloadError?.Invoke(this, M3L.GetString(M3L.string_interp_nexusModNotCompatible, ModFile.Name)); return; } } // download with manager was clicked. // Check if parameters are correct! DownloadLinks.AddRange(NexusModsUtilities.GetDownloadLinkForFile(ProtocolLink).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(ProtocolLink) ?.Result); } ProgressMaximum = ModFile.SizeInBytes ?? ModFile.SizeInKilobytes * 1024L; // SizeKb is the original version. They added SizeInBytes at my request Initialized = true; Log.Information($@"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)); } }); }