public AddGameDialog(GameStats game)
		{
			InitializeComponent();
			_tcs = new TaskCompletionSource<GameStats>();
			_editing = true;
			_game = game;
			if(game == null)
				return;
			ComboBoxResult.SelectedItem = game.Result;
			HeroClass heroClass;
			if(Enum.TryParse(game.OpponentHero, out heroClass))
				ComboBoxOpponent.SelectedItem = heroClass;
			ComboBoxMode.SelectedItem = game.GameMode;
			ComboBoxRegion.SelectedItem = game.Region;
			if(game.GameMode == GameMode.Ranked)
				TextBoxRank.Text = game.Rank.ToString();
			TextBoxRank.IsEnabled = game.GameMode == GameMode.Ranked;
			ComboBoxCoin.SelectedItem = game.Coin ? YesNo.Yes : YesNo.No;
			ComboBoxConceded.SelectedItem = game.WasConceded ? YesNo.Yes : YesNo.No;
			TextBoxTurns.Text = game.Turns.ToString();
			TextBoxDuration.Text = game.Duration;
			TextBoxDuration.IsEnabled = false;
			TextBoxNote.Text = game.Note;
			TextBoxOppName.Text = game.OpponentName;
			BtnSave.Content = "save";
		}
		public static async Task<bool> Upload(string[] logLines, GameMetaData gameMetaData, GameStats game)
		{
			var log = string.Join(Environment.NewLine, logLines);
			var item = new UploaderItem(log.GetHashCode());
			if(InProgress.Contains(item))
			{
				Log.Info($"{item.Hash} already in progress. Waiting for it to complete...");
				InProgress.Add(item);
				return await item.Success;
			}
			InProgress.Add(item);
			Log.Info($"Uploading {item.Hash}...");
			var success = false;
			try
			{
				success = await TryUpload(logLines, gameMetaData, game, true);
			}
			catch(Exception ex)
			{
				Log.Error(ex);
				Influx.OnGameUploadFailed();
			}
			Log.Info($"{item.Hash} complete. Success={success}");
			foreach(var waiting in InProgress.Where(x => x.Hash == item.Hash))
				waiting.Complete(success);
			InProgress.RemoveAll(x => x.Hash == item.Hash);
			return success;
		}
		private static async Task<bool> TryUpload(string[] logLines, GameMetaData gameMetaData, GameStats game, bool submitFailure)
		{
			try
			{
				game?.HsReplay.UploadTry();
				Influx.OnGameUpload(game?.HsReplay.UploadTries ?? 1);
				var lines = logLines.SkipWhile(x => !x.Contains("CREATE_GAME")).ToArray();
				var metaData = UploadMetaDataGenerator.Generate(lines, gameMetaData, game);
				Log.Info("Creating upload request...");
				var uploadRequest = await ApiWrapper.CreateUploadRequest(metaData);
				Log.Info("Upload Id: " + uploadRequest.ShortId);
				await ApiWrapper.UploadLog(uploadRequest, lines);
				Log.Info("Upload complete");
				if(game != null)
				{
					game.HsReplay.UploadId = uploadRequest.ShortId;
					game.HsReplay.ReplayUrl = uploadRequest.ReplayUrl;
					if(DefaultDeckStats.Instance.DeckStats.Any(x => x.DeckId == game.DeckId))
						DefaultDeckStats.Save();
					else
						DeckStatsList.Save();
				}
				return true;
			}
			catch(WebException ex)
			{
				Log.Error(ex);
				if(submitFailure)
					Influx.OnGameUploadFailed(ex.Status);
				return false;
			}
		}
 public string Apply(GameStats game)
 {
     var name = "";
     foreach(var token in Pattern)
     {
         var tokenLower = token.ToLower();
         if(tokenLower == "{playerclass}")
         {
             name += game.PlayerHero;
         }
         else if(tokenLower == "{opponentclass}")
         {
             name += game.OpponentHero;
         }
         else if(tokenLower == "{playername}")
         {
             name += game.PlayerName;
         }
         else if(tokenLower == "{opponentname}")
         {
             name += game.OpponentName;
         }
         else if(tokenLower.Contains("{date:"))
         {
             name += ParseDate(token);
         }
         else
         {
             name += token;
         }
     }
     return name;
 }
		public AddGameDialog(GameStats game)
		{
			InitializeComponent();
			_tcs = new TaskCompletionSource<GameStats>();
			_editing = true;
			_game = game;
			if(game == null)
				return;
			ComboBoxResult.SelectedItem = game.Result;
			HeroClass heroClass;
			if(!string.IsNullOrWhiteSpace(game.OpponentHero) && Enum.TryParse(game.OpponentHero, out heroClass))
				ComboBoxOpponent.SelectedItem = heroClass;
			ComboBoxMode.SelectedItem = game.GameMode;
			ComboBoxFormat.SelectedItem = game.Format;
			ComboBoxRegion.SelectedItem = game.Region;
			if(game.GameMode == Ranked)
			{
				TextBoxRank.Text = game.Rank.ToString();
				TextBoxLegendRank.Text = game.LegendRank.ToString();
			}
			PanelRank.Visibility = PanelLegendRank.Visibility = game.GameMode == Ranked ? Visible : Collapsed;
			PanelFormat.Visibility = game.GameMode == Ranked || game.GameMode == Casual ? Visible : Collapsed;
			ComboBoxCoin.SelectedItem = game.Coin ? Yes : No;
			ComboBoxConceded.SelectedItem = game.WasConceded ? Yes : No;
			TextBoxTurns.Text = game.Turns.ToString();
			TextBoxDuration.Text = game.Duration;
			TextBoxDuration.IsEnabled = false;
			TextBoxNote.Text = game.Note;
			TextBoxOppName.Text = game.OpponentName;
			TextBoxPlayerName.Text = game.PlayerName;
			BtnSave.Content = "save";
			Title = "Edit game";
		}
		public AddGameDialog(Deck deck)
		{
			InitializeComponent();
			_tcs = new TaskCompletionSource<GameStats>();
			_editing = false;
			var lastGame = deck.DeckStats.Games.LastOrDefault();
			if(deck.IsArenaDeck)
			{
				ComboBoxMode.SelectedItem = GameMode.Arena;
				ComboBoxMode.IsEnabled = false;
				TextBoxRank.IsEnabled = false;
			}
			else
			{
				ComboBoxMode.IsEnabled = true;
				TextBoxRank.IsEnabled = true;
				if(lastGame != null)
				{
					ComboBoxMode.SelectedItem = lastGame.GameMode;
					if(lastGame.GameMode == GameMode.Ranked)
						TextBoxRank.Text = lastGame.Rank.ToString();
				}
			}
			if(lastGame != null && lastGame.Region != Region.UNKNOWN)
				ComboBoxRegion.SelectedItem = lastGame.Region;
			_deck = deck;
			_game = new GameStats();
			BtnSave.Content = "add game";
		}
		//LocUtil.Get()}

		public static async Task<MessageDialogResult> ShowDeleteGameStatsMessage(this MetroWindow window, GameStats stats)
			=> await window.ShowMessageAsync(LocUtil.Get(LocDeleteGameStatsTitle),
				stats + Environment.NewLine + Environment.NewLine + LocUtil.Get(LocDeleteGameStatsSure),
				AffirmativeAndNegative,
				new Settings
				{
					AffirmativeButtonText = LocUtil.Get(LocDeleteGameStatsButtonDelete),
					NegativeButtonText = LocUtil.Get(LocDeleteGameStatsButtonCancel)
				});
		public static async Task<MessageDialogResult> ShowDeleteGameStatsMessage(MetroWindow window, GameStats stats)
		{
			var settings = new MetroDialogSettings {AffirmativeButtonText = "Yes", NegativeButtonText = "No"};
			return
				await
				window.ShowMessageAsync("Delete Game",
				                        stats.Result + " vs " + stats.OpponentHero + "\nfrom " + stats.StartTime + "\n\nAre you sure?",
				                        MessageDialogStyle.AffirmativeAndNegative, settings);
		}
		public NoteDialog(GameStats game)
		{
			InitializeComponent();
			_game = game;
			CheckBoxEnterToSave.IsChecked = Config.Instance.EnterToSaveNote;
			Show();
			Activate();
			TextBoxNote.Focus();
			_initialized = true;
		}
        public static GameStats CreateGame(Guid deck, Region region, GameMode mode, int days)
        {
            var game = new GameStats(GameResult.Win, "Mage", "Mage");
            game.DeckId = deck;
            game.Region = region;
            game.GameMode = mode;
            game.StartTime = DateTime.Now.Subtract(TimeSpan.FromDays(days));

            return game;
        }
        public NoteDialog(GameStats game, List<Image> screenshots)
        {
            InitializeComponent();
            _game = game;
            CheckBoxEnterToSave.IsChecked = Config.Instance.EnterToSaveNote;
            Show();
            Activate();
            TextBoxNote.Focus();

            ListBox_Images.DataContext = screenshots;

            _initialized = true;
        }
		public NoteDialog(GameStats game)
		{
			InitializeComponent();
			_game = game;
			CheckBoxEnterToSave.IsChecked = Config.Instance.EnterToSaveNote;
			TextBoxNote.Text = game.Note;
			DeckList.ItemsSource = game.OpponentCards
				.Select(x => new NoteCard(x))
				.OrderBy(x => x.Cost);
			Show();
			Activate();
			TextBoxNote.Focus();
			_initialized = true;
		}
		internal static void ShowGameResultToast(string deckName, GameStats game)
		{
			if(game == null)
				return;
			var result = new ToastHelper(new GameResultToast(deckName, game));
			if(Config.Instance.ShowReplayShareToast)
			{
				var replay = new ToastHelper(new ReplayToast(game));
				GameResultToasts.Add(replay, result);
				ShowToast(result);
				ShowToast(replay);
			}
			else
				ShowToast(result);
		}
示例#14
0
		public static void SaveImage(GameStats game, Image screenshot, String note = null)
		{
			if(game != null)
			{
				if (!String.IsNullOrEmpty(note))
					game.Note = note;
				DeckStatsList.Save();

				if(Config.Instance.StatsInWindow)
				{
					((DeckStatsControl)Helper.MainWindow.StatsWindow.FindName("StatsControl")).Refresh();
				}
				else
				{
					((DeckStatsControl)Helper.MainWindow.FindName("DeckStatsFlyout")).Refresh();
				}

				if(screenshot != null)
				{
					try
					{
						var dir = Settings.Default.OutputDir;
						if(!Directory.Exists(dir))
						{
							dir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
						}
						var pattern = Settings.Default.FileNamePattern;
						NamingPattern np = null;
						if(!NamingPattern.TryParse(pattern, out np))
							Logger.WriteLine("Invalid file name pattern, using default", "EndGame");
						var filename = np.Apply(game);
						SaveAsPng(screenshot.Full, Path.Combine(dir, filename));
					}
					catch(Exception e)
					{
						Logger.WriteLine("Error saving image: " + e.Message, "EndGame");
					}
				}
				else
				{
					Logger.WriteLine("Screenshot is null", "EndGame");
				}
			}
			else
			{
				Logger.WriteLine("Game is null", "EndGame");
			}
		}
		public static async Task<bool> ShowReplay(GameStats game, bool showToast)
		{
			if(game == null)
				return false;
			if(Config.Instance.ForceLocalReplayViewer)
			{
				ReplayReader.LaunchReplayViewer(game.ReplayFile, false);
				return true;
			}
			Action<ReplayProgress> setToastStatus = null;
			if(game.HasReplayFile && !game.HsReplay.Uploaded)
			{
				if(showToast)
					setToastStatus = ToastManager.ShowReplayProgressToast();
				var log = GetLogFromHdtReplay(game.ReplayFile).ToArray();
				var validationResult = LogValidator.Validate(log);
				if(validationResult.IsValid)
					await LogUploader.Upload(log, null, game);
				else
				{
					Log.Error("Invalid log: " + validationResult.Reason);
					game.HsReplay.Unsupported = true;
				}
				if(DefaultDeckStats.Instance.DeckStats.Any(x => x.DeckId == game.DeckId))
					DefaultDeckStats.Save();
				else
					DeckStatsList.Save();
			}
			if(game.HsReplay?.Uploaded ?? false)
			{
				setToastStatus?.Invoke(ReplayProgress.Complete);
				Helper.TryOpenUrl(game.HsReplay?.Url);
			}
			else if(game.HasReplayFile)
			{
				setToastStatus?.Invoke(ReplayProgress.Error);
				ReplayReader.LaunchReplayViewer(game.ReplayFile, true);
			}
			else
			{
				setToastStatus?.Invoke(ReplayProgress.Error);
				return false;
			}
			return true;
		}
		public static UploadMetaData Generate(string[] log, GameMetaData gameMetaData, GameStats game)
		{
			var metaData = new UploadMetaData();
			var playerInfo = GetPlayerInfo(log, game);
			if(playerInfo != null)
			{
				metaData.Player1 = playerInfo.Player1;
				metaData.Player2 = playerInfo.Player2;
			}
			if(!string.IsNullOrEmpty(gameMetaData?.ServerInfo?.Address))
				metaData.ServerIp = gameMetaData.ServerInfo.Address;
			if(gameMetaData?.ServerInfo?.Port > 0)
				metaData.ServerPort = gameMetaData.ServerInfo.Port.ToString();
			if(gameMetaData?.ServerInfo?.GameHandle > 0)
				metaData.GameHandle = gameMetaData.ServerInfo.GameHandle.ToString();
			if(gameMetaData?.ServerInfo?.ClientHandle > 0)
				metaData.ClientHandle = gameMetaData.ServerInfo.ClientHandle.ToString();
			if(!string.IsNullOrEmpty(gameMetaData?.ServerInfo?.SpectatorPassword))
				metaData.SpectatePassword = gameMetaData.ServerInfo.SpectatorPassword;
			if(!string.IsNullOrEmpty(gameMetaData?.ServerInfo?.AuroraPassword))
				metaData.AuroraPassword = gameMetaData.ServerInfo.AuroraPassword;
			if(!string.IsNullOrEmpty(gameMetaData?.ServerInfo?.Version))
				metaData.ServerVersion = gameMetaData.ServerInfo.Version;
			if(game?.StartTime > DateTime.MinValue)
				metaData.MatchStart = game.StartTime.ToString("o");
			if(game != null)
				metaData.GameType = game.GameType != GameType.GT_UNKNOWN ? (int)HearthDbConverter.GetBnetGameType(game.GameType, game.Format) : (int)HearthDbConverter.GetGameType(game.GameMode, game.Format);
			if(game?.Format != null)
				metaData.Format = (int)HearthDbConverter.GetFormatType(game.Format);
			metaData.SpectatorMode = game?.GameMode == GameMode.Spectator;
			metaData.Reconnected = gameMetaData?.Reconnected ?? false;
			metaData.Resumable = gameMetaData?.ServerInfo?.Resumable ?? false;
			metaData.FriendlyPlayerId = game?.FriendlyPlayerId > 0 ? game.FriendlyPlayerId : (playerInfo?.FriendlyPlayerId > 0 ? playerInfo?.FriendlyPlayerId : null);
			var scenarioId = game?.ScenarioId ?? gameMetaData?.ServerInfo?.Mission;
			if(scenarioId > 0)
				metaData.ScenarioId = scenarioId;
			var build = gameMetaData?.HearthstoneBuild ?? game?.HearthstoneBuild ?? (game != null ? BuildDates.GetByDate(game.StartTime) : null);
			if(build > 0)
				metaData.HearthstoneBuild = build;
			if(game?.BrawlSeasonId > 0)
				metaData.BrawlSeason = game.BrawlSeasonId;
			if(game?.RankedSeasonId > 0)
				metaData.LadderSeason = game.RankedSeasonId;
			return metaData;
		}
		public GameResultToast(string deckName, [NotNull] GameStats game)
		{
			InitializeComponent();
			InitializeComponent();
			DeckName = deckName;
			_game = game;
			ComboBoxResult.ItemsSource = new[] { GameResult.Win, GameResult.Loss };
			ComboBoxFormat.ItemsSource = new[] { Enums.Format.Standard, Enums.Format.Wild };
			ComboBoxGameMode.ItemsSource = new[]
			{
				GameMode.Arena,
				GameMode.Brawl,
				GameMode.Casual,
				GameMode.Friendly,
				GameMode.Practice,
				GameMode.Ranked,
				GameMode.Spectator
			};
		}
		private static PlayerInfo GetPlayerInfo(string[] log, GameStats game)
		{
			var friendly = new UploadMetaData.Player();
			var opposing = new UploadMetaData.Player();

			if(game?.Rank > 0)
				friendly.Rank = game.Rank;
			if(game?.LegendRank > 0)
				friendly.LegendRank = game.LegendRank;
			if(game?.PlayerCardbackId > 0)
				friendly.Cardback = game.PlayerCardbackId;
			if(game?.Stars > 0)
				friendly.Stars = game.Stars;
			if(game?.PlayerCards.Sum(x => x.Count) == 30 && game?.PlayerCards.Sum(x => x.Unconfirmed) <= 24)
			{
				friendly.DeckList = game.PlayerCards.Where(x => x.Id != Database.UnknownCardId).SelectMany(x => Enumerable.Repeat(x.Id, x.Count)).ToArray();
				if(game.HsDeckId > 0)
					friendly.DeckId = game.HsDeckId;
			}
			if(game?.ArenaWins > 0)
				friendly.Wins = game.ArenaWins;
			if(game?.ArenaLosses > 0)
				friendly.Losses = game.ArenaLosses;

			if(game?.OpponentRank > 0)
				opposing.Rank = game.OpponentRank;
			if(game?.OpponentLegendRank > 0)
				opposing.LegendRank = game.OpponentLegendRank;
			if(game?.OpponentCardbackId > 0)
				opposing.Cardback = game.OpponentCardbackId;

			if(game?.FriendlyPlayerId > 0)
			{
				return new PlayerInfo(game.FriendlyPlayerId == 1 ? friendly : opposing,
					game.FriendlyPlayerId == 2 ? friendly : opposing);
			}
			var player1Name = GetPlayer1Name(log);
			if(player1Name == game?.PlayerName)
				return new PlayerInfo(friendly, opposing, 1);
			if(player1Name == game?.OpponentName)
				return new PlayerInfo(opposing, friendly, 2);
			return null;
		}
		private static void GenerateTestMatches()
		{
			_match1 = new GameStats(GameResult.Win, "Druid", "Druid");
			_match1.Result = GameResult.Win;
			_match1.Rank = 20;
			_match1.Coin = true;
			_match1.DeckName = _deck1.Name;
			_match1.StartTime = DateTime.Now.AddMinutes(-5);
			_match1.EndTime = DateTime.Now;
			_match1.Region = Region.EU;
			_match1.GameMode = GameMode.Casual;
			_match1.PlayerName = "Epix";
			_match1.OpponentName = "trigun";
			_match1.Turns = 10;

			_match2 = new GameStats(GameResult.Win, "Priest", "Warlock");
			_match2.Result = GameResult.Win;
			_match2.Rank = 19;
			_match2.Coin = true;
			_match2.DeckName = _deck2.Name;
			_match2.StartTime = DateTime.Now.AddMinutes(-7);
			_match2.EndTime = DateTime.Now;
			_match2.Region = Region.US;
			_match2.GameMode = GameMode.Casual;
			_match2.PlayerName = "Epix";
			_match2.OpponentName = "trigun";
			_match2.Turns = 10;

			_match3 = new GameStats(GameResult.Win, "Mage", "Warrior");
			_match3.Result = GameResult.Win;
			_match3.Rank = 18;
			_match3.Coin = false;
			_match3.DeckName = _deck2.Name;
			_match3.StartTime = DateTime.Now.AddMinutes(-6);
			_match3.EndTime = DateTime.Now;
			_match3.Region = Region.ASIA;
			_match3.GameMode = GameMode.Casual;
			_match3.PlayerName = "Epix";
			_match3.OpponentName = "trigun";
			_match3.Turns = 10;
		}
		public AddGameDialog(Deck deck)
		{
			InitializeComponent();
			_tcs = new TaskCompletionSource<GameStats>();
			_editing = false;
			var lastGame = deck.DeckStats.Games.LastOrDefault();
			if(deck.IsArenaDeck)
			{
				ComboBoxMode.SelectedItem = Arena;
				ComboBoxMode.IsEnabled = false;
			}
			else
			{
				ComboBoxMode.IsEnabled = true;
				TextBoxRank.IsEnabled = true;
				TextBoxLegendRank.IsEnabled = true;
				if(lastGame != null)
				{
					ComboBoxFormat.SelectedItem = lastGame.Format;
					ComboBoxMode.SelectedItem = lastGame.GameMode;
					if(lastGame.GameMode == Ranked)
					{
						TextBoxRank.Text = lastGame.Rank.ToString();
						TextBoxLegendRank.Text = lastGame.LegendRank.ToString();
					}
				}
			}
			if(lastGame != null)
			{
				PanelRank.Visibility = PanelLegendRank.Visibility = lastGame.GameMode == Ranked ? Visible : Collapsed;
				PanelFormat.Visibility = lastGame.GameMode == Ranked || lastGame.GameMode == Casual ? Visible : Collapsed;
				TextBoxPlayerName.Text = lastGame.PlayerName;
				if(lastGame.Region != Region.UNKNOWN)
					ComboBoxRegion.SelectedItem = lastGame.Region;
			}
			_deck = deck;
			_game = new GameStats();
			BtnSave.Content = "add game";
			Title = _deck.Name;
		}
		public static async Task<PostResult> UploadMatchAsync(GameStats game, Deck deck, bool saveFilesAfter = true, bool background = false)
		{
			Log.Info("trying to upload match: " + game);
			if(!HearthStatsAPI.IsLoggedIn)
			{
				Log.Error("not logged in");
				return PostResult.Failed;
			}
			if(!HearthStatsAPI.IsValidGame(game))
				return PostResult.Failed;
			if(background)
				AddBackgroundActivity();
			if(!deck.HasHearthStatsId)
			{
				Log.Info("...deck has no HearthStats id, uploading deck");
				var success = await UploadDeckAsync(deck);
				if(!success.Success)
				{
					Log.Error("deck could not be uploaded or did not return an id. Can not upload match.");
					if(background)
						RemoveBackgroundActivity();
					return PostResult.Failed;
				}
			}
			var result = await HearthStatsAPI.PostGameResultAsync(game, deck);
			if(!result.Success && result.Retry)
			{
				await Task.Delay(RetryDelay);
				Log.Info("try #2 to upload match: " + game);
				result = await HearthStatsAPI.PostGameResultAsync(game, deck);
			}
			if(result.Success && saveFilesAfter)
				DeckStatsList.Save();
			if(background)
				RemoveBackgroundActivity();
			if(result.Success)
				Log.Info("success uploading match " + game);
			return result;
		}
		public GameResultNotificationWindow(string deckName, [NotNull] GameStats game)
		{
			InitializeComponent();
			DeckName = deckName;
			_game = game;
			ComboBoxResult.ItemsSource = new[] { GameResult.Win, GameResult.Loss };
			ComboBoxFormat.ItemsSource = new[] { Enums.Format.Standard, Enums.Format.Wild };
			ComboBoxGameMode.ItemsSource = new[]
			{
				GameMode.Arena,
				GameMode.Brawl,
				GameMode.Casual,
				GameMode.Friendly,
				GameMode.Practice,
				GameMode.Ranked,
				GameMode.Spectator
			};
			UpdatePosition();
			_startUpTime = DateTime.UtcNow;
			CloseAsync();
			Log.Info("Now showing");
			Activate();
		}
		public GameResultNotificationWindow(string deckName, [NotNull] GameStats game)
		{
			InitializeComponent();
			DeckName = deckName;
			_game = game;
			ComboBoxOpponentClass.ItemsSource = Enum.GetValues(typeof(HeroClass)).Cast<HeroClass>().Select(x => new HeroClassWrapper(x));
			ComboBoxResult.ItemsSource = new[] {GameResult.Win, GameResult.Loss};
			ComboBoxGameMode.ItemsSource = new[]
			{
				GameMode.Arena,
				GameMode.Brawl,
				GameMode.Casual,
				GameMode.Friendly,
				GameMode.Practice,
				GameMode.Ranked,
				GameMode.Spectator
			};
			UpdatePosition();
			_startUpTime = DateTime.UtcNow;
			CloseAsync();
			Logger.WriteLine("Now showing", "GameResultNotification");
			Activate();
		}
#pragma warning disable 4014
		public static async void HandleGameEnd()
		{
			Helper.MainWindow.Overlay.HideTimers();
			if(Game.CurrentGameStats == null)
				return;
			if(Game.CurrentGameMode == GameMode.Spectator && !Config.Instance.RecordSpectator)
			{
				Logger.WriteLine("Game is in Spectator mode, discarded. (Record Spectator disabled)", "GameEventHandler");
				_assignedDeck = null;
				return;
			}
			var player = Game.Entities.FirstOrDefault(e => e.Value.IsPlayer);
			var opponent = Game.Entities.FirstOrDefault(e => e.Value.HasTag(GAME_TAG.PLAYER_ID) && !e.Value.IsPlayer);
			if(player.Value != null)
				Game.CurrentGameStats.PlayerName = player.Value.Name;
			if(opponent.Value != null && CardIds.HeroIdDict.ContainsValue(Game.CurrentGameStats.OpponentHero))
				Game.CurrentGameStats.OpponentName = opponent.Value.Name;
			else
				Game.CurrentGameStats.OpponentName = Game.CurrentGameStats.OpponentHero;

			Game.CurrentGameStats.Turns = HsLogReader.Instance.GetTurnNumber();
			if(Config.Instance.DiscardZeroTurnGame && Game.CurrentGameStats.Turns < 1)
			{
				Logger.WriteLine("Game has 0 turns, discarded. (DiscardZeroTurnGame)", "GameEventHandler");
				_assignedDeck = null;
				GameEvents.OnGameEnd.Execute();
				return;
			}
			Game.CurrentGameStats.GameEnd();
			GameEvents.OnGameEnd.Execute();
			var selectedDeck = DeckList.Instance.ActiveDeck;
			if(selectedDeck != null)
			{
				if(Config.Instance.DiscardGameIfIncorrectDeck
				   && !Game.PlayerDrawn.All(
				                            c =>
				                            c.IsStolen
				                            || selectedDeck.GetSelectedDeckVersion().Cards.Any(c2 => c.Id == c2.Id && c.Count <= c2.Count)))
				{
					if(Config.Instance.AskBeforeDiscardingGame)
					{
						var discardDialog = new DiscardGameDialog(Game.CurrentGameStats);
						discardDialog.Topmost = true;
						discardDialog.ShowDialog();
						if(discardDialog.Result == DiscardGameDialogResult.Discard)
						{
							Logger.WriteLine("Assigned current game to NO deck - selected deck does not match cards played (dialogresult: discard)",
							                 "GameEventHandler");
							Game.CurrentGameStats.DeleteGameFile();
							_assignedDeck = null;
							return;
						}
						if(discardDialog.Result == DiscardGameDialogResult.MoveToOther)
						{
							var moveDialog = new MoveGameDialog(DeckList.Instance.Decks.Where(d => d.Class == Game.CurrentGameStats.PlayerHero));
							moveDialog.Topmost = true;
							moveDialog.ShowDialog();
							var targetDeck = moveDialog.SelectedDeck;
							if(targetDeck != null)
							{
								selectedDeck = targetDeck;
								Game.CurrentGameStats.PlayerDeckVersion = moveDialog.SelectedVersion;
								Game.CurrentGameStats.HearthStatsDeckVersionId = targetDeck.GetVersion(moveDialog.SelectedVersion).HearthStatsDeckVersionId;
								//...continue as normal
							}
							else
							{
								Logger.WriteLine("No deck selected in move game dialog after discard dialog, discarding game", "GameEventHandler");
								Game.CurrentGameStats.DeleteGameFile();
								_assignedDeck = null;
								return;
							}
						}
					}
					else
					{
						Logger.WriteLine("Assigned current game to NO deck - selected deck does not match cards played (no dialog)", "GameEventHandler");
						Game.CurrentGameStats.DeleteGameFile();
						_assignedDeck = null;
						return;
					}
				}
				else
				{
					Game.CurrentGameStats.PlayerDeckVersion = DeckList.Instance.ActiveDeckVersion.Version;
					Game.CurrentGameStats.HearthStatsDeckVersionId = DeckList.Instance.ActiveDeckVersion.HearthStatsDeckVersionId;
				}

				_lastGame = Game.CurrentGameStats;
				selectedDeck.DeckStats.AddGameResult(_lastGame);
				selectedDeck.StatsUpdated();
				if(Config.Instance.ShowNoteDialogAfterGame && !Config.Instance.NoteDialogDelayed && !_showedNoteDialog)
				{
					_showedNoteDialog = true;
					new NoteDialog(Game.CurrentGameStats);
				}
				Logger.WriteLine("Assigned current game to deck: " + selectedDeck.Name, "GameStats");
				_assignedDeck = selectedDeck;

				// Unarchive the active deck after we have played a game with it
				if(_assignedDeck.Archived)
				{
					Logger.WriteLine("Automatically unarchiving deck " + selectedDeck.Name + " after assigning current game", "GameEventHandler");
					Helper.MainWindow.ArchiveDeck(_assignedDeck, false);
				}

				if(HearthStatsAPI.IsLoggedIn && Config.Instance.HearthStatsAutoUploadNewGames)
				{
					if(Game.CurrentGameMode == GameMode.None)
						await GameModeDetection(300); //give the user 5 minutes to get out of the victory/defeat screen
					if(Game.CurrentGameMode == GameMode.Casual)
						await HsLogReader.Instance.RankedDetection();
					if(Game.CurrentGameMode == GameMode.Ranked && !_lastGame.HasRank)
						await RankDetection(5);
					await GameModeSaved(15);
					if(Game.CurrentGameMode == GameMode.Arena)
						HearthStatsManager.UploadArenaMatchAsync(_lastGame, selectedDeck, background: true);
					if(Game.CurrentGameMode == GameMode.Brawl)
						{ /* do nothing */ }
					else
						HearthStatsManager.UploadMatchAsync(_lastGame, selectedDeck, background: true);
				}
				_lastGame = null;
			}
			else
			{
				DefaultDeckStats.Instance.GetDeckStats(Game.PlayingAs).AddGameResult(Game.CurrentGameStats);
				Logger.WriteLine(string.Format("Assigned current deck to default {0} deck.", Game.PlayingAs), "GameStats");
				_assignedDeck = null;
			}
		}
 protected bool Equals(GameStats other)
 {
     return GameId.Equals(other.GameId);
 }
 public GameStats CloneWithNewId()
 {
     var newGame = new GameStats(Result, OpponentHero) {StartTime = StartTime, EndTime = EndTime, Coin = Coin, GameMode = GameMode, Turns = Turns, _turnStats = LoadTurnStats()};
     newGame.Save();
     return newGame;
 }
示例#27
0
 public void AddGameResult(GameStats gameStats)
 {
     Games.Add(gameStats);
 }
		public static async Task<bool> ShowEditGameDialog(this MetroWindow window, GameStats game)
		{
			if(game == null)
				return false;
			var dialog = new AddGameDialog(game);
			await window.ShowMetroDialogAsync(dialog, new MetroDialogSettings {AffirmativeButtonText = "save", NegativeButtonText = "cancel"});
			var result = await dialog.WaitForButtonPressAsync();
			await window.HideMetroDialogAsync(dialog);
			if(result == null)
				return false;
			if(Config.Instance.HearthStatsAutoUploadNewGames && HearthStatsAPI.IsLoggedIn)
			{
				var deck = DeckList.Instance.Decks.FirstOrDefault(d => d.DeckId == game.DeckId);
				if(deck != null)
				{
					if(game.GameMode == GameMode.Arena)
						HearthStatsManager.UpdateArenaMatchAsync(game, deck, true, true);
					else
						HearthStatsManager.UpdateMatchAsync(game, deck.GetVersion(game.PlayerDeckVersion), true, true);
				}
			}
			DeckStatsList.Save();
			Core.MainWindow.DeckPickerList.UpdateDecks();
			return true;
		}
示例#29
0
 public void Remove(GameStats game) => Remove(game.GameId);
示例#30
0
 public void Add(GameStats game) => Add(game.DeckId, game.GameId, game.PlayerHero);
示例#31
0
 protected bool Equals(GameStats other) => GameId.Equals(other.GameId);
#pragma warning disable 4014
		public async void HandleGameEnd()
		{
			if(_game.CurrentGameStats == null || _handledGameEnd)
			{
				Logger.WriteLine("HandleGameEnd was already called.", "HandleGameEnd");
				return;
			}
			//deal with instant concedes
			if(_game.CurrentGameMode == Casual || _game.CurrentGameMode == None)
				DetectRanks();
			_handledGameEnd = true;
			TurnTimer.Instance.Stop();
			Core.Overlay.HideTimers();
			Logger.WriteLine("Game ended...", "HandleGameEnd");
			if(_game.CurrentGameMode == Spectator && !Config.Instance.RecordSpectator)
			{
				if(Config.Instance.ReselectLastDeckUsed && DeckList.Instance.ActiveDeck == null)
				{
					Core.MainWindow.SelectLastUsedDeck();
					Config.Instance.ReselectLastDeckUsed = false;
					Logger.WriteLine("ReselectLastUsedDeck set to false", "HandleGameEnd");
					Config.Save();
				}
				Logger.WriteLine("Game is in Spectator mode, discarded. (Record Spectator disabled)", "HandleGameEnd");
				_assignedDeck = null;
				return;
			}
			var player = _game.Entities.FirstOrDefault(e => e.Value.IsPlayer);
			var opponent = _game.Entities.FirstOrDefault(e => e.Value.HasTag(PLAYER_ID) && !e.Value.IsPlayer);
			if(player.Value != null)
				_game.CurrentGameStats.PlayerName = player.Value.Name;
			if(opponent.Value != null && CardIds.HeroIdDict.ContainsValue(_game.CurrentGameStats.OpponentHero))
				_game.CurrentGameStats.OpponentName = opponent.Value.Name;
			else
				_game.CurrentGameStats.OpponentName = _game.CurrentGameStats.OpponentHero;

			_game.CurrentGameStats.Turns = LogReaderManager.GetTurnNumber();
			if(Config.Instance.DiscardZeroTurnGame && _game.CurrentGameStats.Turns < 1)
			{
				Logger.WriteLine("Game has 0 turns, discarded. (DiscardZeroTurnGame)", "HandleGameEnd");
				_assignedDeck = null;
				GameEvents.OnGameEnd.Execute();
				return;
			}
			_game.CurrentGameStats.GameEnd();
			GameEvents.OnGameEnd.Execute();
			var selectedDeck = DeckList.Instance.ActiveDeck;
			if(selectedDeck != null)
			{
				if(Config.Instance.DiscardGameIfIncorrectDeck
				   && !_game.Player.DrawnCards.All(
				                                   c =>
				                                   c.IsCreated
				                                   || selectedDeck.GetSelectedDeckVersion().Cards.Any(c2 => c.Id == c2.Id && c.Count <= c2.Count)))
				{
					if(Config.Instance.AskBeforeDiscardingGame)
					{
						var discardDialog = new DiscardGameDialog(_game.CurrentGameStats) {Topmost = true};
						discardDialog.ShowDialog();
						if(discardDialog.Result == DiscardGameDialogResult.Discard)
						{
							Logger.WriteLine("Assigned current game to NO deck - selected deck does not match cards played (dialogresult: discard)",
							                 "HandleGameEnd");
							_game.CurrentGameStats.DeleteGameFile();
							_assignedDeck = null;
							return;
						}
						if(discardDialog.Result == DiscardGameDialogResult.MoveToOther)
						{
							var moveDialog = new MoveGameDialog(DeckList.Instance.Decks.Where(d => d.Class == _game.CurrentGameStats.PlayerHero))
							{
								Topmost = true
							};
							moveDialog.ShowDialog();
							var targetDeck = moveDialog.SelectedDeck;
							if(targetDeck != null)
							{
								selectedDeck = targetDeck;
								_game.CurrentGameStats.PlayerDeckVersion = moveDialog.SelectedVersion;
								_game.CurrentGameStats.HearthStatsDeckVersionId = targetDeck.GetVersion(moveDialog.SelectedVersion).HearthStatsDeckVersionId;
								//...continue as normal
							}
							else
							{
								Logger.WriteLine("No deck selected in move game dialog after discard dialog, discarding game", "HandleGameEnd");
								_game.CurrentGameStats.DeleteGameFile();
								_assignedDeck = null;
								return;
							}
						}
					}
					else
					{
						Logger.WriteLine("Assigned current game to NO deck - selected deck does not match cards played (no dialog)", "HandleGameEnd");
						_game.CurrentGameStats.DeleteGameFile();
						_assignedDeck = null;
						return;
					}
				}
				else
				{
					_game.CurrentGameStats.PlayerDeckVersion = DeckList.Instance.ActiveDeckVersion.Version;
					_game.CurrentGameStats.HearthStatsDeckVersionId = DeckList.Instance.ActiveDeckVersion.HearthStatsDeckVersionId;
				}

				_lastGame = _game.CurrentGameStats;
				selectedDeck.DeckStats.AddGameResult(_lastGame);
				selectedDeck.StatsUpdated();
				if(Config.Instance.ArenaRewardDialog && selectedDeck.IsArenaRunCompleted.HasValue && selectedDeck.IsArenaRunCompleted.Value)
					_arenaRewardDialog = new ArenaRewardDialog(selectedDeck);

				if(Config.Instance.ShowNoteDialogAfterGame && !Config.Instance.NoteDialogDelayed && !_showedNoteDialog)
				{
					_showedNoteDialog = true;
					new NoteDialog(_game.CurrentGameStats);
				}
				Logger.WriteLine("Assigned current game to deck: " + selectedDeck.Name, "HandleGameEnd");
				_assignedDeck = selectedDeck;

				// Unarchive the active deck after we have played a game with it
				if(_assignedDeck.Archived)
				{
					Logger.WriteLine("Automatically unarchiving deck " + selectedDeck.Name + " after assigning current game", "HandleGameEnd");
					Core.MainWindow.ArchiveDeck(_assignedDeck, false);
				}

				if(HearthStatsAPI.IsLoggedIn && Config.Instance.HearthStatsAutoUploadNewGames)
				{
					Logger.WriteLine("Waiting for game mode detection...", "HandleGameEnd");
					await _game.GameModeDetection();
					Logger.WriteLine("Detected game mode, continuing.", "HandleGameEnd");
					Logger.WriteLine("Waiting for game mode to be saved to game...", "HandleGameEnd");
					await GameModeSaved(15);
					Logger.WriteLine("Game mode was saved, continuing.", "HandleGameEnd");
					if(_game.CurrentGameMode == Arena)
						HearthStatsManager.UploadArenaMatchAsync(_lastGame, selectedDeck, background: true);
					else if(_game.CurrentGameMode != Brawl)
						HearthStatsManager.UploadMatchAsync(_lastGame, selectedDeck, background: true);
				}
				_lastGame = null;
			}
			else
			{
				try
				{
					DefaultDeckStats.Instance.GetDeckStats(_game.Player.Class).AddGameResult(_game.CurrentGameStats);
					Logger.WriteLine($"Assigned current deck to default {_game.Player.Class} deck.", "HandleGameEnd");
				}
				catch(Exception ex)
				{
					Logger.WriteLine("Error saving to DefaultDeckStats: " + ex, "HandleGameEnd");
				}
				_assignedDeck = null;
			}

			if(Config.Instance.ReselectLastDeckUsed && selectedDeck == null)
			{
				Core.MainWindow.SelectLastUsedDeck();
				Config.Instance.ReselectLastDeckUsed = false;
				Logger.WriteLine("ReselectLastUsedDeck set to false", "HandleGameEnd");
				Config.Save();
			}
		}
示例#33
0
 protected bool Equals(GameStats other)
 {
     return(GameId.Equals(other.GameId));
 }
		public static async Task<MessageDialogResult> ShowDeleteGameStatsMessage(this MetroWindow window, GameStats stats)
			=> await window.ShowMessageAsync("Delete Game", $"{stats.Result} vs {stats.OpponentHero}\nfrom {stats.StartTime}\n\nAre you sure?",
				AffirmativeAndNegative, new Settings {AffirmativeButtonText = "Yes", NegativeButtonText = "No"});
		public GameStats CloneWithNewId()
		{
			var newGame = new GameStats(Result, OpponentHero, PlayerHero)
			{
				StartTime = StartTime,
				EndTime = EndTime,
				Coin = Coin,
				GameMode = GameMode,
				Turns = Turns,
				_turnStats = LoadTurnStats(),
				PlayerName = PlayerName,
				OpponentName = OpponentName,
				ReplayFile = ReplayFile,
				WasConceded = WasConceded,
				VerifiedHeroes = VerifiedHeroes,
				PlayerDeckVersion = PlayerDeckVersion,
				IsClone = true
			};
			newGame.Save();
			return newGame;
		}