/// <summary> /// Refreshes the <see cref="AllMods"/> list with freshly new downloaded mod informations. /// Keeps the information about mods up-to-date. /// </summary> public Task RefreshMods(bool useCachedOldMods = false, int timeout = 12000) { return(Task.Run(async() => { AllMods = new List <Mod>(); OfflineMods = new List <Mod>(); AllGameVersions = new List <string>(); LastDidRefreshMods = DateTime.Now; CancellationTokenSource cts = new CancellationTokenSource(timeout); using (HttpClient hp = new HttpClient()) { string cacheFile = ALL_MODS_FILE; CacheConfig cache = null; if (File.Exists(cacheFile)) { cache = JsonConvert.DeserializeObject <CacheConfig>(File.ReadAllText(cacheFile)); } // Load offline available mods if (File.Exists(OFFLINE_FILE)) { OfflineMods.AddRange(JsonConvert.DeserializeObject <List <Mod> >(File.ReadAllText(OFFLINE_FILE))); Console.WriteLine($"Loaded { OfflineMods.Count } offline available mods."); } try { HttpResponseMessage gameVersionsResponse = await hp.GetAsync(BeatModsUrlBuilder.AllGameVersionsUrl, cts.Token); gameVersionsResponse.EnsureSuccessStatusCode(); string allGameVersionsJson = await gameVersionsResponse.Content.ReadAsStringAsync(); AllGameVersions = JsonConvert.DeserializeObject <List <string> >(allGameVersionsJson) .OrderByDescending((e) => SemVersionExtenions.AsNumber(e)).ToList(); if (cache != null && (cache.allGameVersions == null || !cache.allGameVersions.SequenceEqual(AllGameVersions))) { cache.allGameVersions = AllGameVersions; File.WriteAllText(cacheFile, JsonConvert.SerializeObject(cache)); Console.WriteLine("Cache file game versions changed."); } IsOffline = false; } catch (Exception e) when(e is HttpRequestException || e is TaskCanceledException) { IsOffline = true; if (cache != null) { AllGameVersions.AddRange(cache.allGameVersions); } AllMods.AddRange(OfflineMods); return; } string mostRecentGameVersion = AllGameVersions.First(); BeatModsQuery query = BeatModsQuery.All; // If mod cache is enabled, only download mod info about the most recent mods if (cache != null && useCachedOldMods && cache.cacheMaxGameVersion == mostRecentGameVersion) { Console.WriteLine($"Loading { cache.cachedMods.Count } mods from cache '{ cacheFile }' until game version { cache.cacheMaxGameVersion }."); query.forGameVersion = cache.cacheMaxGameVersion; AllMods.AddRange(cache.cachedMods); } HttpResponseMessage modsResponse = await hp.GetAsync(query.CreateRequestUrl(), cts.Token); modsResponse.EnsureSuccessStatusCode(); string modsJson = await modsResponse.Content.ReadAsStringAsync(); AllMods.AddRange(JsonConvert.DeserializeObject <List <Mod> >(modsJson)); AllMods = AllMods.Union(OfflineMods).ToList(); if (useCachedOldMods) { // Cache file does not exist, create it and cache all mods but the recent version if (cache == null || cache.cacheMaxGameVersion != mostRecentGameVersion) { cache = new CacheConfig() { cachedMods = AllMods.Where((e) => e.GetGameVersion() < mostRecentGameVersion.FixOddVersion()).ToList(), cacheMaxGameVersion = mostRecentGameVersion, allGameVersions = AllGameVersions }; File.WriteAllText(cacheFile, JsonConvert.SerializeObject(cache)); Console.WriteLine($"Created new cache file '{ cacheFile }' for { cache.cachedMods.Count } mods with max game version { cache.cacheMaxGameVersion }."); } } Console.WriteLine($"Loaded in total { AllMods.Count } mods."); } })); }
public static IEnumerable <Mod> OnlyKeepMostRecentMods(this IEnumerable <Mod> mods) { return(mods.GroupBy(x => x.Name.ToUpper()).Select(x => x.OrderByDescending(e => SemVersionExtenions.AsNumber(e.Version)).First())); }
public IEnumerable <Mod> GetModsWithName(string modName, bool onlyApproved = true) { return(AllMods.Where((e) => string.Compare(e.Name, modName, StringComparison.OrdinalIgnoreCase) == 0) .OnlyKeepStatus(onlyApproved ? ModStatus.Approved : ModStatus.All) .OrderByDescending((e) => SemVersionExtenions.AsNumber(e.Version))); }