/// <summary> /// v0.10.0 caused opponent names to be saved as the hero, rather than the name. /// </summary> private static async void ResolveOpponentNames() { var games = DeckStatsList.Instance.DeckStats.SelectMany(ds => ds.Games) .Where(g => g.HasReplayFile && Enum.GetNames(typeof(HeroClass)).Any(x => x == g.OpponentName)) .ToList(); if (!games.Any()) { Config.Instance.ResolvedOpponentNames = true; Config.Save(); return; } var controller = await Core.MainWindow.ShowProgressAsync("Fixing opponent names in recorded games...", "v0.10.0 caused opponent names to be set to their hero, rather than the actual name.\n\nThis may take a moment.\n\nYou can cancel to continue this at a later time (or not at all).", true); var count = 0; var lockMe = new object(); await Task.Run(() => { Parallel.ForEach(games, (game, loopState) => { if (controller.IsCanceled) { loopState.Stop(); } List <ReplayKeyPoint> replay = ReplayReader.LoadReplay(game.ReplayFile); if (replay == null) { return; } var last = replay.LastOrDefault(); if (last == null) { return; } var opponent = last.Data.FirstOrDefault(x => x.IsOpponent); if (opponent == null) { return; } game.OpponentName = opponent.Name; lock (lockMe) { controller.SetProgress(1.0 * ++count / games.Count); } }); }); await controller.CloseAsync(); if (controller.IsCanceled) { var fix = await Core.MainWindow.ShowMessageAsync("Cancelled", "Fix remaining names on next start?", MessageDialogStyle.AffirmativeAndNegative, new MetroDialogSettings { AffirmativeButtonText = "next time", NegativeButtonText = "don\'t fix" }); if (fix == MessageDialogResult.Negative) { Config.Instance.ResolvedOpponentNames = true; Config.Save(); } } else { Config.Instance.ResolvedOpponentNames = true; Config.Save(); } DeckStatsList.Save(); }
internal static async Task <int> FixOppNameAndClass(List <GameStats> games, ProgressDialogController controller) { var count = 0; var fixCount = 0; var gamesCount = games.Count; var lockMe = new object(); var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }; await Task.Run(() => { Parallel.ForEach(games, options, (game, loopState) => { if (controller.IsCanceled) { loopState.Stop(); return; } List <ReplayKeyPoint> replay; try { replay = ReplayReader.LoadReplay(game.ReplayFile); } catch { return; } var last = replay.LastOrDefault(); if (last == null) { return; } var opponent = last.Data.FirstOrDefault(x => x.IsOpponent); if (opponent == null) { return; } var incremented = false; if (game.OpponentName != opponent.Name) { game.OpponentName = opponent.Name; Interlocked.Increment(ref fixCount); incremented = true; } var heroEntityId = opponent.GetTag(GAME_TAG.HERO_ENTITY); var entity = last.Data.FirstOrDefault(x => x.Id == heroEntityId); if (entity != null) { string hero; if (CardIds.HeroIdDict.TryGetValue(entity.CardId ?? "", out hero) && game.OpponentHero != hero) { game.OpponentHero = hero; if (!incremented) { Interlocked.Increment(ref fixCount); } } } lock (lockMe) { controller.SetProgress(1.0 * ++count / gamesCount); } }); }); return(fixCount); }