Пример #1
0
        private static async Task <AbsolutePath> DownloadMod(Game game, int mod)
        {
            using var client = await NexusApiClient.Get();

            var results = await client.GetModFiles(game, mod);

            var file = results.files.FirstOrDefault(f => f.is_primary) ??
                       results.files.OrderByDescending(f => f.uploaded_timestamp).First();
            var src = _stagingFolder.Combine(file.file_name);

            if (src.Exists)
            {
                return(src);
            }

            var state = new NexusDownloader.State
            {
                ModID  = mod,
                Game   = game,
                FileID = file.file_id
            };
            await state.Download(src);

            return(src);
        }
Пример #2
0
        public async Task <string> GetNexusDownloadLink(NexusDownloader.State archive)
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            var info = await GetModInfo(archive.Game, archive.ModID);

            if (!info.available)
            {
                throw new Exception("Mod unavailable");
            }

            if (await IsPremium())
            {
                if (HourlyRemaining <= 0 && DailyRemaining <= 0)
                {
                    throw new NexusAPIQuotaExceeded();
                }

                var url =
                    $"https://api.nexusmods.com/v1/games/{archive.Game.MetaData().NexusName}/mods/{archive.ModID}/files/{archive.FileID}/download_link.json";
                return((await Get <List <DownloadLink> >(url)).First().URI);
            }

            try
            {
                Utils.Log($"Requesting manual download for {archive.Name} {archive.PrimaryKeyString}");
                return((await Utils.Log(await ManuallyDownloadNexusFile.Create(archive)).Task).ToString());
            }
            catch (TaskCanceledException ex)
            {
                Utils.Error(ex, "Manual cancellation of download");
                throw;
            }
        }
Пример #3
0
        public async Task <string> GetNexusDownloadLink(NexusDownloader.State archive)
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            var url = $"https://api.nexusmods.com/v1/games/{archive.Game.MetaData().NexusName}/mods/{archive.ModID}/files/{archive.FileID}/download_link.json";

            try
            {
                return((await Get <List <DownloadLink> >(url)).First().URI);
            }
            catch (HttpRequestException)
            {
                if (await IsPremium())
                {
                    throw;
                }
            }

            try
            {
                Utils.Log($"Requesting manual download for {archive.Name}");
                return((await Utils.Log(await ManuallyDownloadNexusFile.Create(archive)).Task).ToString());
            }
            catch (TaskCanceledException ex)
            {
                Utils.Error(ex, "Manual cancellation of download");
                throw;
            }
        }
Пример #4
0
        public ModVM(NexusDownloader.State m)
        {
            this.ModName         = NexusApiUtils.FixupSummary(m.ModName);
            this.ModID           = m.ModID;
            this.ModDescription  = NexusApiUtils.FixupSummary(m.Summary);
            this.ModAuthor       = NexusApiUtils.FixupSummary(m.Author);
            this.IsNSFW          = m.Adult;
            this.ModURL          = m.NexusURL;
            this.ImageURL        = m.SlideShowPic;
            this.ImageObservable = Observable.Return(this.ImageURL)
                                   .ObserveOn(RxApp.TaskpoolScheduler)
                                   .SelectTask(async url =>
            {
                try
                {
                    var ret = new MemoryStream();
                    using (Stream stream = await new HttpClient().GetStreamAsync(url))
                    {
                        stream.CopyTo(ret);
                    }

                    ret.Seek(0, SeekOrigin.Begin);
                    return(ret);
                }
                catch (Exception ex)
                {
                    Utils.LogToFile($"Exception while caching slide {this.ModName} ({this.ModID})\n{ex.ExceptionToString()}");
                    return(default(MemoryStream));
                }
            })
                                   .ObserveOn(RxApp.MainThreadScheduler)
                                   .Select(memStream =>
            {
                if (memStream == null)
                {
                    return(default(BitmapImage));
                }
                try
                {
                    var image = new BitmapImage();
                    image.BeginInit();
                    image.CacheOption  = BitmapCacheOption.OnLoad;
                    image.StreamSource = memStream;
                    image.EndInit();
                    image.Freeze();
                    return(image);
                }
                catch (Exception ex)
                {
                    Utils.LogToFile($"Exception while caching slide {this.ModName} ({this.ModID})\n{ex.ExceptionToString()}");
                    return(default(BitmapImage));
                }
                finally
                {
                    memStream?.Dispose();
                }
            })
                                   .Replay(1)
                                   .RefCount();
        }
Пример #5
0
        public async Task <string> GetNexusDownloadLink(NexusDownloader.State archive)
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            var url = $"https://api.nexusmods.com/v1/games/{ConvertGameName(archive.GameName)}/mods/{archive.ModID}/files/{archive.FileID}/download_link.json";

            return((await Get <List <DownloadLink> >(url)).First().URI);
        }
Пример #6
0
        public ModVM(NexusDownloader.State m)
        {
            ModName         = NexusApiUtils.FixupSummary(m.ModName);
            ModID           = m.ModID;
            ModDescription  = NexusApiUtils.FixupSummary(m.Summary);
            ModAuthor       = NexusApiUtils.FixupSummary(m.Author);
            IsNSFW          = m.Adult;
            ModURL          = m.NexusURL;
            ImageURL        = m.SlideShowPic;
            ImageObservable = Observable.Return(ImageURL)
                              .ObserveOn(RxApp.TaskpoolScheduler)
                              .SelectTask(async url =>
            {
                try
                {
                    var ret = new MemoryStream();
                    using (Stream stream = await new HttpClient().GetStreamAsync(url))
                    {
                        stream.CopyTo(ret);
                    }

                    ret.Seek(0, SeekOrigin.Begin);
                    return(ret);
                }
                catch (Exception ex)
                {
                    Utils.Error(ex, $"Exception while caching slide {ModName} ({ModID})");
                    return(default(MemoryStream));
                }
            })
                              .ObserveOn(RxApp.MainThreadScheduler)
                              .Select(memStream =>
            {
                if (memStream == null)
                {
                    return(default(BitmapImage));
                }
                try
                {
                    return(UIUtils.BitmapImageFromStream(memStream));
                }
                catch (Exception ex)
                {
                    Utils.Error(ex, $"Exception while caching slide {ModName} ({ModID})");
                    return(default(BitmapImage));
                }
                finally
                {
                    memStream?.Dispose();
                }
            })
                              .Replay(1)
                              .RefCount();
        }
Пример #7
0
        public string GetNexusDownloadLink(NexusDownloader.State archive, bool cache = false)
        {
            if (cache && TryGetCachedLink(archive, out var result))
            {
                return(result);
            }

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            var url = $"https://api.nexusmods.com/v1/games/{ConvertGameName(archive.GameName)}/mods/{archive.ModID}/files/{archive.FileID}/download_link.json";

            return(Get <List <DownloadLink> >(url).First().URI);
        }
Пример #8
0
        public async Task <EndorsementResponse> EndorseMod(NexusDownloader.State mod)
        {
            Utils.Status($"Endorsing ${mod.GameName} - ${mod.ModID}");
            var url = $"https://api.nexusmods.com/v1/games/{ConvertGameName(mod.GameName)}/mods/{mod.ModID}/endorse.json";

            var content = new FormUrlEncodedContent(new Dictionary <string, string> {
                { "version", mod.Version }
            });

            using (var stream = await HttpClient.PostStream(url, content))
            {
                return(stream.FromJSON <EndorsementResponse>());
            }
        }
Пример #9
0
 public ModVM(NexusDownloader.State m)
 {
     ModName         = NexusApiUtils.FixupSummary(m.ModName);
     ModID           = m.ModID;
     ModDescription  = NexusApiUtils.FixupSummary(m.Summary);
     ModAuthor       = NexusApiUtils.FixupSummary(m.Author);
     IsNSFW          = m.Adult;
     ModURL          = m.NexusURL;
     ImageURL        = m.SlideShowPic;
     ImageObservable = Observable.Return(ImageURL)
                       .ObserveOn(RxApp.TaskpoolScheduler)
                       .DownloadBitmapImage((ex) => Utils.Log($"Skipping slide for mod {ModName} ({ModID})"))
                       .Replay(1)
                       .RefCount(TimeSpan.FromMilliseconds(5000));
 }
Пример #10
0
        public async Task <string> GetNexusDownloadLink(NexusDownloader.State archive, bool cache = false)
        {
            if (cache)
            {
                var result = await TryGetCachedLink(archive);

                if (result.Succeeded)
                {
                    return(result.Value);
                }
            }

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            var url = $"https://api.nexusmods.com/v1/games/{ConvertGameName(archive.GameName)}/mods/{archive.ModID}/files/{archive.FileID}/download_link.json";

            return((await Get <List <DownloadLink> >(url)).First().URI);
        }
Пример #11
0
        private static async Task <AbsolutePath> DownloadNexusFile(Game game, int mod, NexusFileInfo file)
        {
            var src = _stagingFolder.Combine(file.file_name);

            if (src.Exists)
            {
                return(src);
            }

            var state = new NexusDownloader.State
            {
                ModID  = mod,
                Game   = game,
                FileID = file.file_id
            };
            await state.Download(src);

            return(src);
        }
Пример #12
0
        private async Task <Archive> FindAlternatives(NexusDownloader.State state, Hash srcHash)
        {
            var origSize = _settings.PathForArchive(srcHash).Size;
            var api      = await NexusApiClient.Get(Request.Headers["apikey"].FirstOrDefault());

            var allMods = await api.GetModFiles(state.Game, state.ModID);

            var archive = allMods.files.Where(m => !string.IsNullOrEmpty(m.category_name))
                          .OrderBy(s => Math.Abs((long)s.size - origSize))
                          .Select(s =>
                                  new Archive(
                                      new NexusDownloader.State
            {
                Game   = state.Game,
                ModID  = state.ModID,
                FileID = s.file_id
            })
            {
                Name = s.file_name,
                Size = (long)s.size,
            })
                          .FirstOrDefault();

            if (archive == null)
            {
                Utils.Log($"No alternative for {srcHash}");
                return(null);
            }

            Utils.Log($"Found alternative for {srcHash}");

            var indexed = await SQL.DownloadStateByPrimaryKey(archive.State.PrimaryKeyString);

            if (indexed == null)
            {
                return(archive);
            }

            Utils.Log($"Pre-Indexed alternative {indexed.Hash} found for {srcHash}");
            archive.Hash = indexed.Hash;
            return(archive);
        }
Пример #13
0
        private bool TryGetCachedLink(NexusDownloader.State archive, out string result)
        {
            if (!Directory.Exists(Consts.NexusCacheDirectory))
            {
                Directory.CreateDirectory(Consts.NexusCacheDirectory);
            }

            var path = Path.Combine(Consts.NexusCacheDirectory, $"link-{archive.GameName}-{archive.ModID}-{archive.FileID}.txt");

            if (!File.Exists(path) || (DateTime.Now - new FileInfo(path).LastWriteTime).TotalHours > 24)
            {
                File.Delete(path);
                result = GetNexusDownloadLink(archive);
                File.WriteAllText(path, result);
                return(true);
            }

            result = File.ReadAllText(path);
            return(true);
        }
Пример #14
0
        private async Task <GetResponse <string> > TryGetCachedLink(NexusDownloader.State archive)
        {
            if (!Directory.Exists(Consts.NexusCacheDirectory))
            {
                Directory.CreateDirectory(Consts.NexusCacheDirectory);
            }

            var path = Path.Combine(Consts.NexusCacheDirectory, $"link-{archive.GameName}-{archive.ModID}-{archive.FileID}.txt");

            if (!File.Exists(path) || (DateTime.Now - new FileInfo(path).LastWriteTime).TotalHours > 24)
            {
                File.Delete(path);
                var result = await GetNexusDownloadLink(archive);

                File.WriteAllText(path, result);
                return(GetResponse <string> .Succeed(result));
            }

            return(GetResponse <string> .Succeed(File.ReadAllText(path)));
        }
Пример #15
0
        /// <summary>
        /// Takes all the permissions for a given Nexus mods and merges them down to a single permissions record
        /// the more specific record having precedence in each field.
        /// </summary>
        /// <param name="mod"></param>
        /// <returns></returns>
        public Permissions FilePermissions(NexusDownloader.State mod)
        {
            var author_permissions = AuthorPermissions.GetOrDefault(mod.Author)?.Permissions;
            var game_permissions   = AuthorPermissions.GetOrDefault(mod.Author)?.Games.GetOrDefault(mod.GameName)?.Permissions;
            var mod_permissions    = AuthorPermissions.GetOrDefault(mod.Author)?.Games.GetOrDefault(mod.GameName)?.Mods.GetOrDefault(mod.ModID)
                                     ?.Permissions;
            var file_permissions = AuthorPermissions.GetOrDefault(mod.Author)?.Games.GetOrDefault(mod.GameName)?.Mods
                                   .GetOrDefault(mod.ModID)?.Files.GetOrDefault(mod.FileID)?.Permissions;

            return(new Permissions
            {
                CanExtractBSAs = file_permissions?.CanExtractBSAs ?? mod_permissions?.CanExtractBSAs ??
                                 game_permissions?.CanExtractBSAs ?? author_permissions?.CanExtractBSAs ?? true,
                CanModifyAssets = file_permissions?.CanModifyAssets ?? mod_permissions?.CanModifyAssets ??
                                  game_permissions?.CanModifyAssets ?? author_permissions?.CanModifyAssets ?? true,
                CanModifyESPs = file_permissions?.CanModifyESPs ?? mod_permissions?.CanModifyESPs ??
                                game_permissions?.CanModifyESPs ?? author_permissions?.CanModifyESPs ?? true,
                CanUseInOtherGames = file_permissions?.CanUseInOtherGames ?? mod_permissions?.CanUseInOtherGames ??
                                     game_permissions?.CanUseInOtherGames ?? author_permissions?.CanUseInOtherGames ?? true,
            });
        }
Пример #16
0
        public static async Task <ManuallyDownloadNexusFile> Create(NexusDownloader.State state)
        {
            var result = new ManuallyDownloadNexusFile(state);

            return(result);
        }
Пример #17
0
 private ManuallyDownloadNexusFile(NexusDownloader.State state)
 {
     State = state;
 }
Пример #18
0
        public async Task <NexusFileInfo> GetFileInfo(NexusDownloader.State mod)
        {
            var url = $"https://api.nexusmods.com/v1/games/{ConvertGameName(mod.GameName)}/mods/{mod.ModID}/files/{mod.FileID}.json";

            return(await GetCached <NexusFileInfo>(url));
        }
Пример #19
0
 public static Uri ManualDownloadUrl(NexusDownloader.State state)
 {
     return(new Uri($"https://www.nexusmods.com/{state.Game.MetaData().NexusName}/mods/{state.ModID}?tab=files"));
 }