/// <summary> /// Binds the asynchronous. /// </summary> /// <param name="game">The game.</param> /// <returns>Task.</returns> protected virtual async Task BindAsync(IGame game = null) { await TriggerOverlayAsync(true, localizationManager.GetResource(LocalizationResources.Installed_Mods.LoadingMods)); if (game == null) { game = gameService.GetSelected(); } ModFilePopulationInCompleted = false; ActiveGame = game; if (game != null) { var mods = await Task.Run(() => modService.GetInstalledMods(game)); await Task.Run(async() => { await PopulateModFilesAsyncAsync(mods).ConfigureAwait(false); ModFilePopulationInCompleted = true; EvalAchievementCompatibility(mods); }); await Task.Delay(100); Mods = mods.ToObservableCollection(); AllMods = Mods.ToHashSet(); var invalidMods = AllMods.Where(p => !p.IsValid); if (invalidMods.Count() > 0) { await RemoveInvalidModsPromptAsync(invalidMods).ConfigureAwait(false); } var searchString = FilterMods.Text ?? string.Empty; FilteredMods = Mods.Where(p => p.Name.Contains(searchString, StringComparison.InvariantCultureIgnoreCase) || (p.RemoteId.HasValue && p.RemoteId.GetValueOrDefault().ToString().Contains(searchString))).ToObservableCollection(); AllModsEnabled = FilteredMods.Where(p => p.IsValid).Count() > 0 && FilteredMods.Where(p => p.IsValid).All(p => p.IsSelected); if (Disposables != null) { modChanged?.Dispose(); modChanged = null; modChanged = Mods.ToSourceList().Connect().WhenPropertyChanged(s => s.IsSelected).Subscribe(s => { if (!checkingState) { CheckModEnabledStateAsync().ConfigureAwait(false); } }).DisposeWith(Disposables); } var state = appStateService.Get(); InitSortersAndFilters(state); ApplyDefaultSort(); } else { Mods = FilteredMods = new System.Collections.ObjectModel.ObservableCollection <IMod>(); AllMods = Mods.ToHashSet(); } await TriggerOverlayAsync(false); }
public void Dispose() { Console.WriteLine($"Saving { OfflineMods.Count } offline available mods."); SaveOfflineModCache(); OfflineMods.Clear(); AllMods.Clear(); }
private async Task SaveApplication() { _saveToken.Cancel(); _saveToken = new CancellationTokenSource(); try { ApplicationTuple.Config.EnabledMods = AllMods.Where(x => x.Enabled == true).Select(x => x.Tuple.Config.ModId).ToArray(); await ApplicationTuple.SaveAsync(_saveToken.Token); } catch (TaskCanceledException) { /* Ignored */ } }
public AppSummaryViewModel(ApplicationViewModel model) { ApplicationTuple = model.ApplicationTuple; OpenModFolderCommand = new OpenModFolderCommand(this); ConfigureModCommand = new ConfigureModCommand(this); _applicationViewModel = model; // Wait for parent to fully initialize. _applicationViewModel.OnGetModsForThisApp += BuildModList; _applicationViewModel.OnLoadModSet += BuildModList; BuildModList(); SelectedMod = AllMods.FirstOrDefault(); }
IEnumerable <ModViewModel> GetModList(string searchText, bool enabled) { if (string.IsNullOrEmpty(searchText) || string.IsNullOrWhiteSpace(searchText)) { return(AllMods.Where(x => x.IsEnabled == enabled)); } return(AllMods.Where(x => x.IsEnabled == enabled && ( x.Title.ToLowerInvariant().Contains(searchText.ToLowerInvariant()) || x.Description.ToLowerInvariant().Contains(searchText.ToLowerInvariant()) ))); }
/// <inheritdoc /> public ConfigureModsViewModel(ApplicationViewModel model, ModUserConfigService userConfigService) { ApplicationTuple = model.ApplicationTuple; _applicationViewModel = model; _userConfigService = userConfigService; _saveToken = new CancellationTokenSource(); // Wait for parent to fully initialize. _applicationViewModel.OnGetModsForThisApp += BuildModList; _applicationViewModel.OnLoadModSet += BuildModList; BuildModList(); SelectedMod = AllMods.FirstOrDefault(); PropertyChanged += OnSelectedModChanged; UpdateCommands(); }
/// <summary> /// Sorts the function. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sortProp">The sort property.</param> /// <param name="dictKey">The dictionary key.</param> protected virtual void SortFunction <T>(Func <IMod, T> sortProp, string dictKey) { if (FilteredMods != null) { var sortOrder = sortOrders[dictKey]; IComparer <T> comparer = ResolveComparer <T>(dictKey); switch (sortOrder.SortOrder) { case Implementation.SortOrder.Asc: if (comparer != null) { FilteredMods = FilteredMods.OrderBy(sortProp, comparer).ToObservableCollection(); AllMods = AllMods.OrderBy(sortProp, comparer).ToHashSet(); } else { FilteredMods = FilteredMods.OrderBy(sortProp).ToObservableCollection(); AllMods = AllMods.OrderBy(sortProp).ToHashSet(); } SelectedMod = null; break; case Implementation.SortOrder.Desc: if (comparer != null) { FilteredMods = FilteredMods.OrderByDescending(sortProp, comparer).ToObservableCollection(); AllMods = AllMods.OrderByDescending(sortProp, comparer).ToHashSet(); } else { FilteredMods = FilteredMods.OrderByDescending(sortProp).ToObservableCollection(); AllMods = AllMods.OrderByDescending(sortProp).ToHashSet(); } SelectedMod = null; break; default: break; } foreach (var sort in sortOrders.Where(p => p.Value != sortOrder)) { sort.Value.SetSortOrder(Implementation.SortOrder.None); } SaveState(); } }
public IOrderedEnumerable <Mod> GetModsCached(BeatModsQuery query) { return(query.sort.SortModList(AllMods.Where((e) => query.MatchesIgnoreSort(e)), !query.sortDescending)); }
public Mod GetModFromLocal(InstalledMod mod) { return(AllMods.FirstOrDefault((e) => e.Version == mod.Version && string.Compare(e.Name, mod.Name, StringComparison.OrdinalIgnoreCase) == 0)); }
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))); }
public Mod GetModFromId(string id) { return(AllMods.FirstOrDefault((e) => string.Compare(e.Id, id, StringComparison.OrdinalIgnoreCase) == 0)); }
//build mod data templates from mods.min.json and mod_types.min.json, also builds search templates for stats used by relevant mods //MUST BE DONE AFTER TRANSLATION DEFINITIONS ARE LOADED IN STATTRANSLATOR public static int LoadMods(string modsfile, string typesfile) { Dictionary <string, Dictionary <string, HashSet <string> > > typesdata = JsonSerializer.Deserialize <Dictionary <string, Dictionary <string, HashSet <string> > > >(File.ReadAllText(typesfile)); AllMods = JsonSerializer.Deserialize <Dictionary <string, PoEModData> >(File.ReadAllText(modsfile)); CoreMods = new Dictionary <string, PoEModData>(); Enchantments = new Dictionary <string, PoEModData>(); InitStatTemplates(); afflictionmods.Clear(); Dictionary <string, string> clusterreminders = new Dictionary <string, string>(); using (StreamReader r = File.OpenText(@"Data\ClusterText.txt")) { string line; string name = null; string desc = null; while ((line = r.ReadLine()) != null) { if (line.Length == 0 && name != null) { clusterreminders.Add(name, desc); name = null; desc = null; continue; } if (name == null) { name = line; } else if (desc == null) { desc = line; } else { desc += "\n" + line; } } if (name != null) { clusterreminders.Add(name, desc); } } //Dictionary<string, List<PoEModWeight>> afflictiondict = new Dictionary<string, List<PoEModWeight>>(); foreach (string k in AllMods.Keys) { PoEModData d = AllMods[k]; //translate once and save string as a property StatTranslator.FillTranslationData(d); //set type_tags field with a lookup d.type_tags = typesdata[d.type]["tags"]; //set key field d.key = k; if (d.generation_type == ModLogic.Enchantment) { Enchantments.Add(k, AllMods[k]); } //flag relevant mods to move to core dictionary, "misc" domain is for regular jewels if ((d.domain == "item" || d.domain == "abyss_jewel" || d.domain == "misc" || d.domain == "affliction_jewel") && (d.generation_type == ModLogic.Prefix || d.generation_type == ModLogic.Suffix)) { CoreMods.Add(k, AllMods[k]); } //every mod worth translating into string templates to search by, doesn't include implicits because idk how to include them w/o also including a ton of useless unique item mods if ((d.domain == "item" || d.domain == "abyss_jewel" || d.domain == "misc" || d.domain == "affliction_jewel" || d.domain == "crafted" || d.domain == "delve") && (d.generation_type == ModLogic.Prefix || d.generation_type == ModLogic.Suffix)) { IncludeTranslations(AllMods[k]); } if ((d.domain == "affliction_jewel") && (d.generation_type == ModLogic.Prefix || d.generation_type == ModLogic.Suffix)) { int notableindex = d.full_translation.IndexOf("Skill is"); if (notableindex > 0 && !d.full_translation.Contains("Jewel Socket")) { string notablename = d.full_translation.Substring(notableindex + 9); d.tooltip_reminder = clusterreminders[notablename]; } //if (d.full_translation.Contains("also grant")) // Debug.WriteLine(d); foreach (PoEModWeight w in d.spawn_weights) { if (w.tag.Contains("affliction")) { afflictionmods.Add(w.tag); //if (d.full_translation.Contains("also grant")) // Debug.WriteLine(w.tag); //if (notableindex > 0 && !d.full_translation.Contains("Jewel Socket")) //{ // if (!afflictiondict.ContainsKey(w.tag)) // afflictiondict.Add(w.tag, new List<PoEModWeight>() { new PoEModWeight() { tag = k, weight = w.weight } }); // else // afflictiondict[w.tag].Add(new PoEModWeight() { tag = k, weight = w.weight }); //} } } } } //using (StreamWriter w = File.CreateText("notables.csv")) //{ // foreach (string s in afflictiondict.Keys) // { // w.WriteLine(s); // foreach (PoEModWeight mw in afflictiondict[s]) // { // PoEModData mod = AllMods[mw.tag]; // w.WriteLine(mw.weight + ",\"" + mod.full_translation.Substring(mod.full_translation.IndexOf("Skill is") + 9) + "\",\"" + mod.tooltip_reminder + "\""); // } // w.WriteLine(""); // } //} Debug.WriteLine(CoreMods.Count + " core, " + Enchantments.Count + " enchantment, " + AllMods.Count + " total mods loaded"); Debug.WriteLine(StatTemplates.Count + " statlines loaded"); IList <string> mediumenchants = new List <string>() { "affliction_area_damage", "affliction_aura_effect", "affliction_brand_damage", "affliction_critical_chance", "affliction_curse_effect", "affliction_fire_damage_over_time_multiplier", "affliction_chaos_damage_over_time_multiplier", "affliction_physical_damage_over_time_multiplier", "affliction_cold_damage_over_time_multiplier", "affliction_damage_over_time_multiplier", "affliction_effect_of_non-damaging_ailments", "affliction_life_and_mana_recovery_from_flasks", "affliction_flask_duration", "affliction_damage_while_you_have_a_herald", "affliction_minion_damage_while_you_have_a_herald", "affliction_minion_life", "affliction_projectile_damage", "affliction_totem_damage", "affliction_trap_and_mine_damage", "affliction_warcry_buff_effect", "affliction_channelling_skill_damage" }; IList <string> smallenchants = new List <string>() { "affliction_maximum_life", "affliction_chance_to_dodge_attacks", "affliction_cold_resistance", "affliction_chaos_resistance", "affliction_armour", "affliction_evasion", "affliction_fire_resistance", "affliction_maximum_mana", "affliction_maximum_energy_shield", "affliction_lightning_resistance", "affliction_chance_to_block" }; IList <string> largeenchants = new List <string>() { "affliction_axe_and_sword_damage", "affliction_mace_and_staff_damage", "affliction_dagger_and_claw_damage", "affliction_bow_damage", "affliction_wand_damage", "affliction_damage_with_two_handed_melee_weapons", "affliction_attack_damage_while_dual_wielding_", "affliction_attack_damage_while_holding_a_shield", "affliction_attack_damage_", "affliction_spell_damage", "affliction_chaos_damage", "affliction_cold_damage", "affliction_elemental_damage", "affliction_fire_damage", "affliction_lightning_damage", "affliction_physical_damage", "affliction_minion_damage" }; IList <PoEModWeight> afflictionmediumspawns = new List <PoEModWeight> { new PoEModWeight() { tag = "expansion_jewel_medium", weight = 100 }, new PoEModWeight() { tag = "default", weight = 0 } }; IList <PoEModWeight> afflictionsmallspawns = new List <PoEModWeight> { new PoEModWeight() { tag = "expansion_jewel_small", weight = 100 }, new PoEModWeight() { tag = "default", weight = 0 } }; IList <PoEModWeight> afflictionlargespawns = new List <PoEModWeight> { new PoEModWeight() { tag = "expansion_jewel_large", weight = 100 }, new PoEModWeight() { tag = "default", weight = 0 } }; IList <PoEModWeight> afflictionnospawns = new List <PoEModWeight> { new PoEModWeight() { tag = "default", weight = 0 } }; foreach (string s in afflictionmods) { PoEModData afflictionmod = new PoEModData() { adds_tags = new HashSet <string>() { s }, domain = "item", generation_type = "enchantment", generation_weights = new List <PoEModWeight>(), group = "SmallPassiveGroup", is_essence_only = false, name = s.Replace("affliction", "small passives grant: "), required_level = 1, stats = null, type = "SmallPassiveType", key = s, type_tags = new HashSet <string>() }; if (mediumenchants.Contains(s)) { afflictionmod.spawn_weights = afflictionmediumspawns; } else if (smallenchants.Contains(s)) { afflictionmod.spawn_weights = afflictionsmallspawns; } else if (largeenchants.Contains(s)) { afflictionmod.spawn_weights = afflictionlargespawns; } else { afflictionmod.spawn_weights = afflictionnospawns; } Enchantments.Add(s, afflictionmod); AllMods.Add(s, afflictionmod); } return(CoreMods.Count); }
private void SaveApplication() { ApplicationTuple.Config.EnabledMods = AllMods.Where(x => x.Enabled == true).Select(x => x.Tuple.Config.ModId).ToArray(); ApplicationTuple.Save(); }
/// <summary> /// Binds the asynchronous. /// </summary> /// <param name="game">The game.</param> /// <param name="skipOverlay">if set to <c>true</c> [skip overlay].</param> /// <returns>Task.</returns> protected virtual async Task BindAsync(IGame game = null, bool skipOverlay = false) { var raiseGameChanged = game != null; GameChangedRefresh = false; var id = idGenerator.GetNextId(); if (!skipOverlay) { await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.Installed_Mods.LoadingMods)); } if (game == null) { game = gameService.GetSelected(); } ModFilePopulationCompleted = false; ActiveGame = game; if (game != null) { if (raiseGameChanged) { GameChangedRefresh = true; } var mods = await Task.Run(async() => await modService.GetInstalledModsAsync(game)); await Task.Run(async() => { await PopulateModFilesAsyncAsync(mods).ConfigureAwait(false); ModFilePopulationCompleted = true; EvalAchievementCompatibility(mods); }); await Task.Delay(100); Mods = mods.ToObservableCollection(); AllMods = Mods.ToHashSet(); var invalidMods = AllMods.Where(p => !p.IsValid); if (invalidMods.Any()) { await Dispatcher.UIThread.SafeInvokeAsync(async() => { await RemoveInvalidModsPromptAsync(invalidMods).ConfigureAwait(false); }); } var searchString = FilterMods.Text ?? string.Empty; FilteredMods = modService.FilterMods(Mods, searchString).ToObservableCollection(); AllModsEnabled = FilteredMods.Where(p => p.IsValid).Any() && FilteredMods.Where(p => p.IsValid).All(p => p.IsSelected); if (Disposables != null) { modChanged?.Dispose(); modChanged = null; modChanged = Mods.ToSourceList().Connect().WhenPropertyChanged(s => s.IsSelected).Subscribe(s => { if (!checkingState) { CheckModEnabledStateAsync().ConfigureAwait(false); } }).DisposeWith(Disposables); } var state = appStateService.Get(); InitSortersAndFilters(state); ApplyDefaultSort(); } else { if (raiseGameChanged) { GameChangedRefresh = true; } Mods = FilteredMods = new System.Collections.ObjectModel.ObservableCollection <IMod>(); AllMods = Mods.ToHashSet(); } if (!skipOverlay) { await TriggerOverlayAsync(id, false); } }